Back to Blog

Latency compensation improvements, coming soon in Meteor 0.5.1

November 19, 2012 By David Glasser
Vote on Hacker News

One of the biggest changes in the upcoming Meteor 0.5.1 release is an improvement to ourlatency compensation algorithm. Meteor keeps things snappy by caching a portion of your app's database in the client's memory. It's not just a read-only cache: when the client sends a database change to the server, it simultaneously updates its local cache with its proposed change. This means the client doesn't have to wait for a roundtrip to update the user's screen. But thesesimulated updates to the local cache only survive until the client finds out what actually happened on the server. If these results differ, Meteor replaces the simulated write with the real server result. This latency compensation requires no extra effort on the developer's part: Meteor takes care of all the bookkeeping behind the scenes. Since the client can pipeline multiple writes, the tricky bit of this bookkeeping is only replacing simulated results on the client when subsequent simulations don't depend on them.

In previous versions of Meteor, every new simulation implicitly depended on every outstanding method. Before doing any optimistic writes to the local cache, we took a snapshot of the entirelocal database cache, and stopped applying any data changes from the server. Once all update methods finished executing on the server, we reverted the entire database back to the snapshot (reverting all of the client-side changes) and applied all of the server's buffered data changes in one fell swoop. In the normal case where all methods succeeded, this would apply the exact same changes from the server as the simulation (and nothing on the screen would need to be updated), but if the method had failed, this would revert the local database back to the server's value. If several write methods were executing at the same time, Meteor would wait until all of them were finished to do this "undo client changes, apply server changes" step.

This strategy worked well and did a good job of keeping the client's cache consistent with the server, but it wasn't perfect. Notably, if a write method was slow, then all server-side data changes would be ignored by the client until the method was done. So with the old code, if your app had a chat room on top and a spaceship launch control panel on the bottom, and it takes 10 minutes to launch a spaceship, the chat room updates would be delayed until the shuttle had finished launching. We need a way to keep the chat room up to date with the latest information from the server, even though the launch control panel is still waiting to get confirmation of the shuttle launch.

So in Meteor 0.5.1, we've make latency compensation more nuanced. Now, instead of freezing the contents of the entire database during every method call, Meteor snapshots the individual data documents (Mongo documents in the current implementation, though the interface is designed to work with any locally-cached database backend) that are updated client-side. Data changes to other documents are now applied directly without being buffered. So your chat room keeps running while you're in the middle of your launch countdown.

Vote on Hacker News