On 3 Feb 2010, at 14:52, Artūras Šlajus wrote:
- unit construction status should be updated.
I imagine that other status updates will add up to this time
period (1 minute). Run updaters as separate ruby processes. Pretty
complex to code.
Perhaps there would be any other ideas that I’ve missed?
A few observations based on my own experiences of writing real-time
systems. YMMV.
To start with there are many architectural assumptions implicit in the
scenario you’ve outlined that you should reconsider to see if they’re
justified, not least of which is that you’re apparently trying to do all
of this through a single server application. Even if you were doing this
in C/C++ I’d view that as a huge disaster waiting to happen.
The rule of thumb with any “real-time” system is to break it down into
as many discrete parts as you can and to have these running as separate
services so that individual bottlenecks can be identified and scaled out
to separate hardware when load demands.
Is it really necessary that all of these updates happen concurrently?
And if not how would you prioritise the updates? Is it possible to limit
the updates to just those players who are logged on and active? Or
perhaps a slightly larger group of which they’re a subset? Perhaps you
can even partition the game world into zones where updates to an
individual zone can be scheduled in isolation.
Examine your query logs and figure out how much overhead you’re paying
for each type of query you run. It could be that for some updates you
should abandon ActiveRecord and use embedded SQL where you can tailor
the query to your specific requirements.
You should also look at message queues for handling your updates. This
will allow you to move the heavy data processing work into separate
processes and make scaling much easier to get your head around. With a
bit of thought you can probably turn what appears to be an atomic update
process into a staged pipeline which more effectively uses the
underlying computing resources at your disposal.
Depending on how much control you have over your database configuration
you could also look at sharding (the zone-splitting already mentioned is
a simple example of this), data denormalisation, and decoupling the
database behind a series of simple web services.
Finally don’t treat writes as immediate updates of the live data as
that’s a very difficult contract to fulfil. Instead consider each update
a discrete ‘turn’. Read the wikipedia article on Shannon-Nyquist and
you’ll see that with the right duty cycle you can make any digital
system appear continuous
Also, based on the architecture you’ve described I’m not sure
EventMachine is a good approach to your problems. It’s really designed
for handling i/o traffic where latency is less of a consideration than
the need to handle many concurrent requests in a mostly timely fashion.
I hope there are some ideas in there that help. You might also find
various useful bits of code in the presentations linked from my
signature.
Ellie
raise ArgumentError unless @reality.responds_to? :reason