Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a simple way to simulate lag with Meteor?

Tags:

meteor

is there a way to simulate lag with Meteor? Perhaps something that would delay all calls by say, 300ms?

like image 601
Stephan Tual Avatar asked Apr 30 '13 07:04

Stephan Tual


3 Answers

I guess I'm a bit late for the party, but here's a better solution:

There are basically two parts to this question. One is, how to delay Meteor WebSocket (SockJS) writes and one is how to delay HTTP traffic (connect). You'll need to add both of the following snippets to your server-side code in order to delay all traffic sent from the Meteor server.

WebSocket

The hard part was overwriting the WebSocket write to delay it with a setTimeout:

(function () {
  // Set the delay you want
  var timeout = 3000
  // stream_server abstracts sockJS the DDP-Server talks to it. 
  var streamServer = Meteor.server.stream_server
  // The connect event listener
  var standardConnect = streamServer.server._events.connection

  // Overwrite the default event-handler
  streamServer.server._events.connection = function (socket) {
    // Overwrite the writes to the socket
    var write = socket.write
    socket.write = function () {
      var self = this
      var args = arguments
      // Add a delay
      setTimeout(function () {
        // Call the normal write methods with the arguments passed to this call
        write.apply(self, args)
      }, timeout)
    }
    // Call the normal handler after overwritting the socket.write function
    standardConnect.apply(this, arguments)
  }
})()

HTTP

With connect it's pretty straight forward:

// Add a simple connect handler, wich calls the next handler after a delay
WebApp.rawConnectHandlers.use(function (req, res, next) {
  return setTimeout(next, timeout)
})
like image 169
halbgut Avatar answered Sep 28 '22 15:09

halbgut


You can do it in publish using:

Meteor._sleepForMs(5000); // sleeps for 5 seconds
like image 44
Eliezer Steinbock Avatar answered Sep 28 '22 13:09

Eliezer Steinbock


Not sure about all calls, but you can use Futures to add a lag on the server, that way you can see latency compensation in action.

In a meteor method for example, you can

Meteor.methods({
  post: function(post) {
    post.title = post.title + (this.isSimulation ? '(client)' : '(server)');

    // wait for 5 seconds
    if (! this.isSimulation) {
      var Future = Npm.require('fibers/future');
      var future = new Future();
      Meteor.setTimeout(function() {
        future.ret();
      }, 5 * 1000); // 5 seconds
      future.wait();
    }
    var postId = Posts.insert(post);
    return postId;
  }
});

This will show the post being inserted with (client) appended to the end, and then 5 seconds later will get the update from the server and post's title will end with (server)

like image 28
Patrick Lee Scott Avatar answered Sep 28 '22 14:09

Patrick Lee Scott