ObjectBox Go 1.1

The 1.1 release of ObjectBox for Go is now available, bringing new features such as Box insert() and update() semantics, a new AsyncBox with all write operations (put, insert, update, delete), improved Queries with order and aliases; as well as some fixes and quality of life improvements, such as time. Time support or more forgiving generator code validation. For the full list of changes see the changelog.

To upgrade to the latest version, run go get -u in your project and don’t forget to re-run the generator to make sure all the code is in sync and you get the new features:

go get -u github.com/objectbox/objectbox-go go generate ./… 1 2 go get - u github . com / objectbox / objectbox - go go generate . / …

Async Box

The new AsyncBox gives you asynchronous processing for write operations such as Put, Insert, Update, Remove, RemoveId.

First a quick reminder how a standard (synchronous) Box works:

box := model.BoxForTask(ob) // Create id, _ := box.Put(&model.Task{ Text: "Buy milk", }) task, _ := box.Get(id) // Read task.Text += " & some bread" box.Put(task) // Update box.Remove(task) // Delete 1 2 3 4 5 6 7 8 9 10 11 box : = model . BoxForTask ( ob ) // Create id , _ : = box . Put ( & model . Task { Text : "Buy milk" , } ) task , _ : = box . Get ( id ) // Read task . Text += " & some bread" box . Put ( task ) // Update box . Remove ( task ) // Delete

Now, let’s have a look at the new AsyncBox. Let’s say tasks are processed in multiple iterations by calling a “ WorkOn(*Task) ”. Let’s also assume that WorkOn() sets a “finished” flag on the object if it was able to complete a task in an iteration. In that case, the task can be removed from the database. Otherwise, partial progress on the task should be saved for the next iteration.

asyncBox := box.Async() var tasks = QueryTasksToWorkOn() for _, task := range tasks { WorkOn(task) // Consumes some CPU time if task.finished { // Remove a finished task asyncBox.Remove(task) } else { // Save progress on task asyncBox.Update(task) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 asyncBox : = box . Async ( ) var tasks = QueryTasksToWorkOn ( ) for _ , task : = range tasks { WorkOn ( task ) // Consumes some CPU time if task . finished { // Remove a finished task asyncBox . Remove ( task ) } else { // Save progress on task asyncBox . Update ( task ) } }

So, what’s the advantage of using AsyncBox in this example? Because we don’t wait for updating or removing a task, we just created an efficient pipeline: we can spend all computational resources on WorkOn(), while AsyncBox performs persistence in the background. Both steps never have to wait for each other.

The second advantage of AsyncBox is “transaction merging.” Because “WorkOn” takes some time, we operate on a single object at a time. A synchronous solution would require a transaction per object, introducing significant disk overhead. AsyncBox can reduce the amount of transactions required and thus dramatically improve throughput.

You may also have noted the usage of “Update()” instead of the standard “Put”. An update is different from a put as it only persists the object if it already exists in the database. Let’s say our example has another process that removes Tasks; a standard put operation might “resurrect” a task previously removed by the other process. If we don’t want that to happen, we can use update semantics. The new update and insert operations are also available in the standard Box API.

Please let us, and everyone else, know what you like about this release and ObjectBox in general. We’d love to hear from you to know what you’d like to see next.

Looking for an easy way to sync data between devices? Check out ObjectBox Sync, sign up for early access, and look out for the release early 2020!