Latency Compensation

 You know that nasty waiting period between something that you do and the result in your browser? That’s what the Latency Compensation proposes to solve, producing immediate results.

As one of the seven principles of Meteor, you have Latency Compensation “almost” for free. Almost … You should be aware of how to program, to use or even to avoid this feature when necessary.

Submit with and without Latency Compensation.

</tr> </tbody> </table>

The difference here again, involves the 7 Meteor principles, Database Everywhere. Meteor maintains a reduced database version on the client, enabling the emulation and avoiding roundtrips.

When a change happens, Meteor simulates what probably will happen, changing the local collections (client), at the same time save the original data in a different collection (originals). These changes in local collections, trigger the Blaze, which detects changes in the data used in the templates, changing the UI, generating immediate results.

Once the simulation ends the client starts to send  DDP messages to the server in order to reproduce the same changes in the main base. When processing ends, the server sends reply messages with the result of what happened. If an error message is received, the client undoes everything that was done during the simulation, otherwise, Meteor will diff data that what was just received, with the originals(client) and if any divergence is found, the originals are changed, with the new informations that came from the server. After the synchronization, local collections are changed with the data from the originals, keeping client and server in sync.

Image 2015-05-14 at 9.24.24 PM.png

Let’s see a simple example, simulating the inclusion of a new post on the client and then getting server not only confirmation but also a change in the title. To demonstrate this, I will use the same line of examples of Discover Meteor.

[code language=”javascript”]
Meteor.methods ({
insert: function (post) {
if (Meteor.isServer) {
post.title + = "<- Server ‘
Meteor._sleepForMs (3000);
} else {
post.title + = "<- Client"
}
Posts.insert (post);
}
});
[/code]

How to implement latency compensation.

You should be aware that the latency compensation only works when you write directly in the databases, eg Posts.insert ({…}) or through method calls.

If you are writing directly on the bases, no problems, you do not have to do anything, but if you are using methods, they (methods) need to be implemented on both, client and server sides. But how?

Two ways, if you are using Meteor.isClient and Meteor.isServer, let your methods out of both, it makes methods available for both. If you are using a directory structure client, lib, server, put your methods in the lib directory.

But beware, even putting everything in the right place, you could end up preventing the latency compensation, let’s see some examples.

As I said earlier, if you are writing directly on the bases without problems, you don’t have to do anything, so this is naturally latency compensated.

[code language=”javascript”]
Posts.insert ({title: Fake.sentence (5), content: Fake.paragraph (2)});
[/code]

So lets get down to the methods.

Let’s see what happens when a method that is only on the server is called by the client.

[code language=”javascript”]
if (Meteor.isClient) {
Template.posts.events ({
‘Click .postar’: function (e) {
e.preventDefault ();
Meteor.call (‘insert’, {title: Fake.sentence (5), content: Fake.paragraph (2)})
alert ("post added").
}
});
}

if (Meteor.isServer) {
Meteor.methods ({
insert: function (post) {
if (Meteor.isServer) {
// Make an HTTP call. *, Performs some lengthy operation, etc …
Meteor._sleepForMs (5000);
}
Posts.insert (post);
}
});
}
[/code]

What happened here? Because the method is on the server and only on the server, client has no way to simulate the execution because it has no idea of what happens inside and has no choice, just to wait until the end of execution, even what is not client’s business.

Now let’s see what happens if we take this method from within the server and put it in a place where both client and server are able to access this code, separating the client, server, and both.

[code language=”javascript”]
if (Meteor.isClient) {
Template.posts.events ({
‘Click .postar’: function (e) {
e.preventDefault ();
Meteor.call (‘insert’, {title: Fake.sentence (5), content: Fake.paragraph (2)})
alert ("post added").
Test ();
}
});
}

Meteor.methods ({
insert: function (post) {
if (Meteor.isServer) {
// Perform some HTTP. * Call, performs some lengthy operation, etc …
Meteor._sleepForMs (5000);
}
Posts.insert (post);
}
});

if (Meteor.isServer) {
}
[/code]

This time, with code visible for both, the client was able to perform just what was relevant to, without having to wait for the execution of server code.

Ok! But what if I really need to leave the code on the server?

So in that case you need Meteor.defer ()

[code language=”javascript”]
if (Meteor.isServer) {
Meteor.methods ({
insert: function (post) {
Meteor.defer (function () {
// Perform some HTTP. * Call, performs some lengthy operation, etc …
Meteor._sleepForMs (5000);
});
post.title + = "<- defer"
Posts.insert (post);
}
});
}
[/code]

See that our code returned completely to the server, but using the Meteor.defer, execution does not hold.

Conclusion

In the end, despite being a fairly accessible resource, you need to decide when to use and when to avoid latency compensation. There are no clearly defined rules to help make that kind of decisions, but, I hope this post has given you a little help to understanding this feature.

With Latency Compensation

</td>

Without Latency Compensation

1 – Submit

1 – Submit

2 – Meteor.call(‘some method’)

2 – Client post to the server

3 – Client simulates the operation

3 – Client wait for server answer

4 – Client uses simulation result and send to server

4 – Update client’s screen with modifications

5 – Client receives the answer from server

6 – If anything wrong happened, client undoes what is not right

Allan de Queiroz

Allan de Queiroz
London based software engineer

XServer forward from Linux text mode for Headless purposes.

Hello, this post is about XServer forward from Linux text mode, **not ssh forward, anything related to VNC** or things like that.Recently...… Continue reading