views:

155

answers:

3

I'm writing a game server in node.js, and some operations involve heavy computation on part of the server. I don't want to stop accepting connections while I run those computations -- how can I run them in the background when node.js doesn't support threads?

A: 

and some operations involve heavy computation on part of the server

How did you write code that is computation heavy in the first place. That's very hard to do in node.js.

how can I run them in the background when node.js doesn't support threads

you could spawn a couple of worker(node) instances and communicate with accepting connections(node instance) using for example redis blocking pop. Node.js redis library is none blocking.

Alfred
It's not hard at all. I'm looping over a game map that's 128x128x128 = 2 million blocks, or larger and calculating things.
nornagon
... or any sort of image processing.
nornagon
This approach should work. You should do some divide and conquer by message passing(blocking list operations).
Alfred
redis is unsuitable for the kind of data I want to process...
nornagon
lol you don't do the processing via redis, but the communication between long running worker processes and main event loop. BTW you can store arbitrarily data in redis.
Alfred
yeah, redis is not suitable for storing this data :)
nornagon
like I said earlier you use redis as intercommunication between the process. Redis makes this very easy/fast. If at all possible to store the data in redis, would be a plus, but not neccessary.
Alfred
+2  A: 

I can't vouch for either of these, personally, but if you're hell-bent on doing the work in-process, there have been a couple of independent implementations of the WebWorkers API for node, as listed on the node modules page:

  • http://github.com/cramforce/node-worker
  • http://github.com/pgriess/node-webworker

At first glance, the second looks more mature, and these would both allow you to essentially do threaded programming, but it's basically actor-model, so it's all done with message passing, and you can't have shared data structures or anything.

Also, for what it's worth, the node.js team intends to implement precisely this API natively, eventually, so these tools, even if they're not perfect, may be a decent stopgap.

Andrew Pendleton
ryah suggested node-webworker when i asked him this question :)
nornagon
+2  A: 
var spawn = require('child_process').spawn;
listorwhatev = spawn('ls', ['-lh', '/usr']);//or whatever server action you need

//then you can attach events to that list like this
listorwhatev.on('exit', function(code){});

///or in this ls example as it streams info
listorwhatev.stdout.on('data', function(info){sys.puts(info);});

ensure spawn process occurs once per application then feed stuff into it and watch it for events per connection. you should also check that the listorwhatev is still running before handling it. As we all love those uncaught errors in node crashing the app don't we ;) When the spawn (pid) is exited though a kill or something bad happens on your machine and you didn't exit the spawn in your code gracefully, your stream event handler will crash your app.

dryprogrammers
I will be passing several megabytes of data back and forth; stdout/stdin don't really feel optimal...
nornagon