The Easter mgo release

It wasn’t just the bunny that was active over the holidays. The r2012.04.08 release of the mgo MongoDB driver for Go has just been tagged. This release is supposed to be entirely compatible with the last release, and there are some nice improvements and a few important bug fixes, so upgrading is recommended.

For the impatient, here is a quick summary of the changes performed:

Bug in Limit method fixed

Overflow in marshaling of time.Time fixed

omitempty support for time.Time fields

Better slave selection

Hard per-server connection limit

Improved performance of query error checking

Sort method arguments simplified

Added Session.Fsync, FsyncLock, and FsyncUnlock methods

Added Query.Snapshot method

If you want more details about any of these, keep reading.

Bug in Limit method fixed

The Limit method was fixed. It was improperly causing the data to be returned in a single chunk from the server, which would mean less documents being processed if the data retrieved went over 4MB. Thanks to Jeff Wendling for reporting the issue.

Overflow in marshaling of time.Time fixed

The marshaling of time.Time was overflowing due to the use of UnixNano, which means certain times would be marshaled as an arbitrarily wrong time. The zero time is an important case that was mishandled, for example. If there’s a chance your application may be affected, you may look for this date in the database to confirm:

1754-08-30 22:43:41.128654848 +0000 UTC

If you find it, that’s actually a zero time.

The problem was fixed and such times will now be marshaled correctly. Thanks to Mikael for reporting the issue on the mgo-users mailing list.

omitempty support for time.Time fields

The omitempty bson tag flag is now supported for time.Time values as well. If used, the time is only marshalled into the bson document if IsZero is false. For example:

type Person struct {
Birthday time.Time `bson:”,omitempty”`
}

Better slave selection

The slave selection algorithm was changed so that mgo will now pick the server for which it has the least number of connections open at the moment, rather than being a random selection. More improvements in this area will come soon.

Hard per-server connection limit

There’s now a hard limit for the number of concurrent connections to a single server. If that limit is reached, the client will block waiting for connections to be released.

The default limit is currently 4096 connections per server for each mgo client, but this logic will be improved in the near future as well to take into account the number of connections currently available at the server side.

Note that this is a fire protection mechanism. This limit is not supposed to be touched under normal operation. If you have higher needs right now, please get in touch.

The development of this feature was sponsored by Iron.io.

Improved performance of query error checking

The logic that verified query results for errors was on the expensive side for large documents, as pointed out by Nils Hasenbanck in the mailing list. This has been significantly improved.

Sort method arguments simplified

The Sort method now takes a list of field names as arguments rather than a document. Field names may be potentially prefixed by – (minus) to sort in descending order.

For example, what would previously be written as:

query := c.Find(q).Sort(bson.M{“a”: 1, “b”: -1})

Is now written as:

query := c.Find(q).Sort(“a”, “-b”)

The previous format is still supported right now for compatibility reasons, but it is deprecated and will eventually be dropped entirely.

The new Session Fsync method requests a synchronous or asynchronous flush of in-memory changes to disk, while the FsyncLock and FsyncUnlock methods do the opposite: they handle a lock at the server side that blocks any follow up write requests (and read requests too, see the documentation). This is useful, for example, to perform backups reliably.