Non-blocking server loop in Node.js with process.nextTick()

For discussions about game development that does not fit in any of the other topics.
Post Reply
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Non-blocking server loop in Node.js with process.nextTick()

Post by Jackolantern »

Some of you may remember I started a conversation a while back wondering how you would do background-processing for a game server made in Node.js. In traditional multithreaded game servers, you actually create a literal loop with something like WHILE(true) so that the server loops through all the tasks it has to do again and again. Of course, since node is single-threaded, you cannot do this or you will block the event loop and break the whole application. Well, I finally wrapped my head around process.nextTick(), and it seems like a great solution for many circumstances (see my note below).

Basically, process.nextTick() defers execution of the function given as its argument until the next "tick", or loop through of the master event loop in node. If you have CPU-intensive code to run, or need something run repetitively (such is the case with a game server), you can set up an event loop-friendly server loop like this:

Code: Select all

function serverMainLoop() {
   //do all processing needed for background activity.
   //this includes moving around mobs, resolving monster AI
   //changing from day to night, and anything else that needs
   //to be done but not in response to a player-initiated event
   
   process.nextTick(serverMainLoop);
}

serverMainLoop();
If instead of using process.nextTick() on the last line of the function you had simply called serverMainLoop() directly, this would have caused an infinite loop, and no input, output or any other events would occur in your application due to "CPU starvation". Essentially the serverMainLoop() function would take the single thread of the server and never give it back.

But by instead deferring the next run of the serverMainLoop() function until the next tick of the server, this means that the serverMainLoop() function will not run again until all other events that are queued-up in the event loop have occurred. This means that websocket communications, file I/O, database communication, etc. all get their chance to run before the server loop starts up again.

However, this is not perfect for all situations. If you have a particularly long server loop with tons of processing, you may be better off with real child processes. Also, this method would probably work best by keeping the majority of the game world state in-memory, and simply set up a JS timer to commit it to the database every few minutes.

Hope this helps for anyone out there wanting to use node for an MMORPG or MUD server but who had a hard time grappling with asynchronous programming and the event loop model of node. :cool:
The indelible lord of tl;dr
User avatar
hallsofvallhalla
Site Admin
Posts: 12026
Joined: Wed Apr 22, 2009 11:29 pm

Re: Non-blocking server loop in Node.js with process.nextTic

Post by hallsofvallhalla »

Oh this is very kewl. The Tick system is the way to go and glad you took the time to investigate it. You would not believe the work around I have already used that this would have made much simpler :)
Post Reply

Return to “General Development”