Current recommended practice for this.unblock in subscriptions

Hi,

Quick question. We are currently going through a phase of performance improvements on our Meteor application. One thing which we have not yet done is use much ‘this.unblock’ in our methods and subscriptions. Reading some slightly old articles it seems that this was debated a little and the general consensus was to put this statement in all (?) publications and selected methods. It also seems there was some talk about making this the default behaviour in Meteor core without having to use any external (meteorhacks:unblock) packages.

Can anyone provide some up to date advice on the current recommended suggestions for using this.unblock?

Any help appreciated!

Rick

I’m currently nearing completion on an article which compares using “traditional” methods with async methods. Part of that comparison looks in detail at this.unblock() - what it does and what the potential pitfalls are.

There are some misconceptions around what this.unblock() will do for your app’s performance. The article’s not quite ready for publication yet, but the key takeaways are:

  • Methods are independent between different clients: So for example, client A can call method 1 at the same time as client B calls method 1 - those methods will run in parallel*. Using this.unblock() to help improve this will do nothing - it’s already running as efficiently as it can.
  • For any one client:
  • Methods are executed in the order they are called from the client. Imagine a FIFO queue on the server for each client.
  • If this.unblock() is not used, methods are also evaluated in order. The method runs to completion and then the queue is popped for the next method to execute.
  • If this.unblock() is used, methods may be evaluated out of order. The queue is popped until empty, each method starting up in a new fiber as soon as it’s popped. Methods finish independently of the order in which they were initially present in the queue. This may result in unpredictable interleaving which is a recipe for hard-to-diagnose, race-induced bugs. If you need to take advantage of this approach, you also need to be certain that it’s safe if your methods complete out of order.

There is no this.unblock() for publications. However, if you have many publications and they take a long time to set up, you can set them up asynchronously, which may help. Try this pattern for each publication:

Meteor.setTimeout(() => {
  Meteor.publish('myPublication', function() {
    // ... standard publication code here, e.g.
    return myCollection.find();
  });
}, 0);

* Not really: node is single threaded, so any CPU bound method will always hold off any other process until it completes. However, if the method is running asynchronous code, then the event loop will be made available to other clients, allowing multiple instances of the method to execute together.

8 Likes

Thanks Rob! I look forward to the article.

So if I read this correctly basically we need to be only putting this.unblock in methods where we have a whole bunch of ‘non-dependent’ async method calls which we really don’t care the order in which each is returned? I guess that limits its use-case to only select places…

Your setTimeout example on the publications is interesting. I am guessing that simulates a similar thing to this.unblock. Would you suggest having this wrapped around all publications?

Also you didn’t make any reference to the meteorhacks:unblock package. Just wondering if you had any thoughts on that?

Thanks again
Rick

1 Like

Well, that’s the safest way to use it - and it’s on a per-client basis. So look at it first from the perspective of the client - “am I firing off multiple method calls ‘simultaneously’?”, and if so, then look at what will happen on the server if those methods complete in a different order to that which you expect.

In my experience, this.unblock() is almost never needed, but YMMV!

I’ve never used it, so can’t comment - sorry.

You’re welcome :slight_smile:

1 Like