Event driven server that wastes CPU when threaded doesn't

S

Snor

I'm attempting to create a lobby & game server for a multiplayer game,
and have hit a problem early on with the server design. I am stuck
between using a threaded server, and using an event driven server. I've
been told time and time again that I should use an event driven server
design (that is, use twisted).

There is a lot of interaction between the clients and they would often
need to write to the same list of values, which of course becomes a
problem with a threaded server - so event driven solves that problem,
and I assumed it would solve all my problems. However some requests
from clients would require that the server goes on to query a mySQL
server (separate machine from the server). As this occurs, there is a
small amount of lag while the communication with the mySQL server takes
place, and there could be another 100 clients waiting to make a request
at this point, meanwhile the server is idling while waiting for a
response from the mySQL server - obviously not a good server model.

I will want the server to support as many users as is possible on any
given machine - and so wasted CPU cycles is something I am trying to
avoid.

Is the only solution to use a threaded server to let my clients make
their requests and receive a response in the fastest possible time?
 
F

Fredrik Lundh

Snor wrote:

Is the only solution to use a threaded server to let my clients make
their requests and receive a response in the fastest possible time?

since the problem is that you need to wait for database anyway, maybe
you could use one or more threads to deal with the database, and keep
using events to talk to the clients?

</F>
 
B

Bjoern Schliessmann

Snor said:
There is a lot of interaction between the clients and they would
often need to write to the same list of values, which of course
becomes a problem with a threaded server - so event driven solves
that problem, and I assumed it would solve all my problems.

Which problem, and why "of course"? Sorry, I can't follow you
here :)
I will want the server to support as many users as is possible on
any given machine - and so wasted CPU cycles is something I am
trying to avoid.

I'm not exactly sure how you connect to that SQL server ... you
shouldn't wait for the response of the MySQL server in a blocking
way, but either using dataReceived() method of the protocol
instance or, if that isn't possible, by using a Deferred instance
that fires when the answer is available. This is also possible with
your client connections.

Regards,


Björn
 
N

Nick Vatamaniuc

Snor,

The simplest solution is to change your system and put the DB on the
same machine thus greatly reducing the time it takes for each DB query
to complete (avoid the TCP stack completely). This way you might not
have to change your application logic.

If that is not an option, then you are faced with a problem of
connecting a threaded programming model with an event based model
(twisted and and such). So your job is to interface the two. In other
words make the event based model see the threaded DB access as event
based. And the DB driver to see the event-based system as threaded. So
in your event dispatcher you could add events like db_request_finished
then when a connection is requested to the DB, a callback will be
supplied. The connection will take place in its own thread, then when
it is finished it will put the db_request_finished and the respective
callback function on the event queue. I am not sure how to integrate
that into the Twisted event dispatcher... perhaps this class is the
answer?:
http://twistedmatrix.com/documents/current/api/twisted.python.dispatch.EventDispatcher.html

Hope this helps,
Nick V.
 
C

Carl Banks

Snor said:
As this occurs, there is a
small amount of lag while the communication with the mySQL server takes
place, and there could be another 100 clients waiting to make a request
at this point, meanwhile the server is idling while waiting for a
response from the mySQL server - obviously not a good server model.

Isn't it possible to use asynchronous communication to talk to the SQL
server as well?

I don't know a lot about Twisted, but I'd think you could create some
sort of connection with the SQL server and have TwistedMatrix manage
and react to the SQL server events the same as it does with your
clients. Being that SQL is so common, I bet someone's already written
higher-level protocol handlers.


Carl Banks
 
P

Paul Rubin

Nick Vatamaniuc said:
The simplest solution is to change your system and put the DB on the
same machine thus greatly reducing the time it takes for each DB query
to complete (avoid the TCP stack completely).

Since when do any db's let you avoid the TCP stack, even on the same
machine?
 
N

Nick Vatamaniuc

Good point. enterprise.adbapi is designed to solve the problem. The
other interface was deprecated.

Thanks,
Nick Vatamaniuc
 
B

Bjoern Schliessmann

Nick said:
If that is not an option, then you are faced with a problem of
connecting a threaded programming model with an event based model
(twisted and and such).

I don't really see how threads could avoid a problem with delays in
one connection ...

Regards,


Björn
 
F

Fredrik Lundh

Bjoern said:
I don't really see how threads could avoid a problem with delays in
one connection ...

by running the database queries in one or more separate threads, you can
still serve requests that don't hit the database (either because they're
entirely self-contained, or because they only rely on cached data).

</F>
 
B

Bryan Olson

Snor said:
I'm attempting to create a lobby & game server for a multiplayer game,
and have hit a problem early on with the server design. I am stuck
between using a threaded server, and using an event driven server. I've
been told time and time again that I should use an event driven server
design (that is, use twisted).

I didn't hear the specifics of how you got that advice, so I
can't comment specifically. I will say that I've have heard a
lot of advice against threads that struck me as simply naive.
There is a lot of interaction between the clients and they would often
need to write to the same list of values, which of course becomes a
problem with a threaded server - so event driven solves that problem,
and I assumed it would solve all my problems. [...]

The purely event-driven style solves some problems, but creates
others. You're forced to structure your code around the blocking
behavior, and that's not the structure anyone would choose for
clarity or maintainability.

Suppose we're enhancing an event-driven system, and decide to
relocate some datum from a variable to the database. Suppose in
one or more places, accessing the data happens in a call chain
several function down from the event loop. We can't just change
the function that accesses the data because a synchronous
database call could block and stop event processing. Every
interface on the call chain is broken.


[...]
I will want the server to support as many users as is possible on any
given machine - and so wasted CPU cycles is something I am trying to
avoid.

Python is a great scripting language, but squeezing out machine
performance is not where scripting languages shine. That said, you
might start in Python, to see if your system is successful and the
performance of your server really is a limiting factor.

Is the only solution to use a threaded server to let my clients make
their requests and receive a response in the fastest possible time?

Maybe. Probably not. It's all good -- multi-threading is your friend.
 
B

Bjoern Schliessmann

Fredrik said:
by running the database queries in one or more separate threads,
you can still serve requests that don't hit the database (either
because they're entirely self-contained, or because they only rely
on cached data).

Nothing that couldn't also be solved without threads. :)

Regards,


Björn
 
M

Magnus Lycka

Snor said:
I'm attempting to create a lobby & game server for a multiplayer game,
and have hit a problem early on with the server design. I am stuck
between using a threaded server, and using an event driven server. I've
been told time and time again that I should use an event driven server
design (that is, use twisted). [snip]
Is the only solution to use a threaded server to let my clients make
their requests and receive a response in the fastest possible time?

You got a lot of long-winded replies, but the short reply is that
Twisted has packaged solutions for this. See
http://twistedmatrix.com/projects/core/enterprise

"Twisted provides an interface to any Python DB-API 2.0 compliant
database through an asynchronous interface which allows database
connections to be used, and multiplexed by multiple threads, while still
remaining thread-safe for use with Twisted's event-based main loop.
Twisted Enterprise provides these services by leveraging Twisted
Internet's utilities for managing thread pools and asynchronous
programming."
 
S

Snor

You got a lot of long-winded replies, but the short reply is that
Twisted has packaged solutions for this. Seehttp://twistedmatrix.com/projects/core/enterprise

"Twisted provides an interface to any Python DB-API 2.0 compliant
database through an asynchronous interface which allows database
connections to be used, and multiplexed by multiple threads, while still
remaining thread-safe for use with Twisted's event-based main loop.
Twisted Enterprise provides these services by leveraging Twisted
Internet's utilities for managing thread pools and asynchronous
programming."

Thanks for this - exactly what I needed. Thanks for the other replies
too even if they weren't so much help :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,107
Latest member
Vinay Kumar Nevatia_
Top