Search code examples
javascriptmeteortimeoutfiber

Unblocking Meteor.logout and login


I have two methods on the server side that look like this:

var Future = require("fibers/future");

Meteor.methods({
  foo: function () {
     this.unblock();
     var f = new Future();
     setTimeout(function () {
         f.return(42);
     }, 10000);
     return f.wait();
  },
  bar: function () {
     return 43;
  }
});

When calling these methods from the client side (using the browser console), they work fine (foo waits 10 seconds and bar just works instantly):

Meteor.call("foo", function (err, data) {
   console.log(err || data);
   // After 10 seconds: 42
});

Meteor.call("bar", function (err, data) {
   console.log(err || data);
   // Very quick (*instantly*): 43
});

However, when having a session and we call Meteor.logout(fn), the callback (fn), will wait after foo is done.

I don't want that. I want the logout method to work like bar (to not wait for the finishing of foo, but work instantly).

How can I do that? Is there a way to unblock logout or something similar? The login operation works in the same way (currently): it waits until foo sends the response.


Solution

  • This the expected behavior of the logout method. It waits until everything is done on the server and then logs out the user.

    Supposing you're using the accounts package (which creates the Accounts global variable), you can look at the source code where the logout method is defined:

    logout(callback) {
        var self = this;
        self.connection.apply('logout', [], {
          wait: true
        }, function (error, result) {
          if (error) {
            callback && callback(error);
          } else {
            self.makeClientLoggedOut();
            callback && callback();
          }
        });
    }
    

    If you really want the logout to work instantly, you can override the Accounts.logout function by turning off the wait option:

    // Override the method and turn off the `wait` field
    Accounts.logout = function () {
        var self = this;
        self.connection.apply('logout', [], {
          wait: false
        }, function (error, result) {
          if (error) {
            callback && callback(error);
          } else {
            self.makeClientLoggedOut();
            callback && callback();
          }
        });
    };
    

    (notice the wait:false in the code above)

    This may crash the things (especially on the client side) because Meteor.user() will be null after logout, but this has to be tested. I expect that on the server (in the context of a server method) the Meteor.user() will be the right object even in the mean time the user logged out.