views:

58

answers:

2

I'm working on a turn-based web game that will perform all world updates (player orders, physics, scripted events, etc.) on the server. For now, I could simply update the world in a web request callback. Unfortunately, that naive approach is not at all scalable. I don't want to bog down my web server when I start running many concurrent games.

So what is the best way to separate the load from the web server, ideally in a way that could even be run on a separate machine?

  • A simple python module with infinite loop?
  • A distributed task in something like Celery?
  • Some sort of cross-platform Cron scheduler?
  • Some other fancy Django feature or third-party library that I don't know about?

I also want to minimize code duplication by using the same model layer. That probably means my service would need access to the Django model code, so that definitely determines how I architect the service.

A: 

I'd just write the backend to just use the Django database interface (look at the setup code in your manage.py), spawn it as its own process, and interface to it with Protocol Buffers. That route should move to a separate machine with little work. MPI may be an option, too.

Pipes, FIFOs, and most other IPC requires both processes to be on the same box.

Though I have to point out a flaw in your premise:

Unfortunately, that naive approach is not at all scalable. I don't want to bog down my web server when I start running many concurrent games.

If you run concurrent games, so long as you keep all the parts for a given game on the same server, this is a non-issue, unless there's a common resource needed by all games. Then the real issue becomes load balancing across the servers.

Mike DeSimone
Thanks, I'll check out manage.py and Protocol Buffers. Regarding the "flaw" in my premise, I think you misunderstand me. The three parts of the application (web server, database, and back-end service) can be on the same machine, and probably will be for a while, but they don't need to be. I want to make sure I design with an eye towards having these pieces on separate machines when needed.
MikeWyatt
Well, if you go through Django's ORM, the database can be on any machine you need it. So the web server to back end connection is the only one at issue. Do you have a requirement that all web services be on one machine? I was thinking you would, eventually, have one machine as a balancer that would find another host (with its own web server) with available capacity and then redirect the request to that server (also informing that server of the session, so people don't just connect direct to a secondary server).
Mike DeSimone
I'm planning on handling all communication through the database. That's what I've traditionally done at work. Web users would submit turn orders, which are then saved to the database. The service would then pickup the updated orders and update the world, which would then be read back by the web site. Load balancing the service would simply be a matter of adding more servers and making sure they don't update the same records.
MikeWyatt
+4  A: 

I think Celery, which you mention in your question, is the way to go here. It will interface nicely with the rest of your setup, support your eventual aim of separating out the systems, and is compatible with Django.

Daniel Roseman
I've been looking at Celery more since posting the question, and it definitely looks useful.
MikeWyatt
+1: i second that, i didn't know about celery
eruciform
Someone is already using celery for a web-site game, though I can't remember who that was :(
asksol