• Meteor

Unblocking a Method

From the class:  RPC with Meteor Methods

Meteor methods get processed sequentially on the server. In this video, I'd like to show you how that works. In this example on the client, I'm calling the Meteor method first, and then right after that calling another Meteor method that's named second.

On the server, both of these Meteor methods just print to the console that were inside of the respective method. But the first one sleeps for five seconds. What the sleep function will do is just pause the currently executing fiber for some specified period of time.

If you're unfamiliar with how fibers and futures work, you can go and watch those videos in the feed. But this sleep function will just pause the currently executing fiber for five seconds. And what that means is that the second Meteor method will not get called until this one is done five seconds from now.

And that's because Meteor methods are processed sequentially. If we want to be able to call the second method right away, we can unblock that queue by calling the unblock method inside of our first Meteor method. So here if I were to say this dot unblock, now, even though the fiber's going to sleep for five seconds, Meteor will still go ahead and process the second Meteor method call right away.

Let me get rid of this and fire up the server and show you how this works in the console. The Meteor application server is running up here. And the console client side debugger is running down in the lower right.

Now, notice on the client, we made the first two Meteor method calls. And what I've done in the debugger is navigated over to the Network tab. And we're looking at the WebSocket DDP frames.

Here you see these two method calls being made. And notice the timing on them. They're made almost right away on the client, so right next to each other.

Now, on the server, notice that the first method gets called at about this time. And then five seconds go by before the second method gets called. And if we want to see that more clearly, I'll go ahead and refresh the debugger. And you can watch.

So you can see that I'm inside the first method, string getting printed. And a couple seconds go by. And then finally the second method gets called.

To see how unblock works, I can say this dot unblock inside the first method. This time, notice what happens. They both get called at about the same time.

I've taken us over to Meteor core into the live data package. And we're looking at the live data server file now. I want to show you the process message function. And this is the function off of session that's going to process the DDP messages.

And so here's the parameter, message in. And we'll scroll down a little bit so that you can see the part that processes these messages sequentially. The first thing to note is the message gets pushed onto this queue.

And so you can imagine that there's this array-like queue. And we have message one gets pushed onto it, and then message two and message three, and so on. And these messages could be things like a subscription message to subscribe or a method message to call a Meteor method.

The next thing to look at is this process next function, which is what's going to iterate over this queue of messages. And the process next function gets called down here, kicking off the iteration.

Now, inside the process next function, first it's going to grab the message that's next in the queue. So maybe that's message one here. And then it's going to create a fiber and run the fiber. And inside of it, it'll call the protocol handler for the particular message.

And so for example, it might call the method protocol handler, which will then invoke our Meteor method. But notice this function called unblock that's passed in as a parameter. And what unblock does is it calls process next again, which continues the iteration and moves us to the next message.

Now, if nothing calls unblock inside of our handler-- for example, we don't call this dot unblock inside of our Meteor method-- then once the method has returned, Meteor will call unblock for us automatically. But all of this logic happens inside of the fiber. And so if we pause this currently executing fiber, the unblock function never actually gets called for us, even automatically. And so we either have to do that ourselves or wait for the fiber to or the function to return so that Meteor will call unblock for us automatically.

Let me scroll down a little bit more and show you the actual protocol handlers for the various messages. Here's the protocol handler for a Meteor method. And notice that the message gets passed in as a first param, and then the unblock function as a second. And then this gets attached to the this object for our method call. And that's why we're able to call unblock on it.

Now, if we scroll up, you'll notice that the subscription particle handler does not actually take in the unblock function as a parameter. And so I'm not sure exactly why this is. But in your subscription functions, there's actually no way to call unblock from within your subscription functions. Only within Meteor methods.

So what this means is that inside of your methods or your subscription functions, if you do something that blocks the currently executing fiber or pauses it for a little while, it's going to hold up processing of all of the future DDP messages for that session. And so if you're going to be doing anything expensive in your Meteor methods, like making an external HTTP call to an API, for example, or sleeping for whatever reason, or doing async work, you'll probably want to call the unblock method to allow the DDP server to continue processing the next messages. And if you're inside of a subscription function, be careful that you don't do too much work inside of the subscription function that would hold up the rest of the DDP messages getting processed.

In this video, we looked at how our Meteor methods are processed sequentially. And more generally, DDP messages for a given session are processed sequentially. We saw how that worked by looking at the process message function and seeing how each one of our protocol handlers is called within its own fiber.

Then we looked at how we can use the unblock function inside of our method functions in order to tell the session to process the next DDP message Finally, we looked at some of the implications of this, namely, if we're going to do expensive things inside of our Meteor methods, we should normally call this dot unblock, and how to, inside of our subscriptions, be careful not to do too much heavy lifting so that we don't tie up the processing queue.