[muscle] Re: ReflectServer::ServerProcessLoop

  • From: Jeremy Friesner <jaf@xxxxxxxxxxxx>
  • To: muscle@xxxxxxxxxxxxx
  • Date: Tue, 24 Aug 2004 14:20:06 -0700

Hi Wilson,

On Tuesday 24 August 2004 11:30, Wilson Yeung wrote:
> But that makes it difficult to integrate external event loops.  In many
> event loops, there's the notion of  do_loop(), which runs until forced
> exit or error, and do_once() which returns after one iteration of the
> loop so that other tasks can be scheduled and run, and then do_once()
> is called again ... and again ... and again. :)
>
> I couldn't find the equivalent in ReflectServer.  Is there some thought
> of adding such a thing?

Such a thing could be added, but I don't think it would be very useful.  The 
reason why it wouldn't be useful is because each iteration of MUSCLE's event 
loop includes a call to select() that blocks until some I/O is ready to be 
sent or received (or until a PulseNode timeout expires).  That means that 
either:

(a) do_once() would include the call to select(), in which case do_once() 
might not return for a long time, and your other event loops' events wouldn't 
necessarily be handled in a timely manner (or perhaps ever!)

or

(b) do_once() would not call select(), in which case you would either have to 
handle all the I/O blocking logic yourself (which would be very awkward and 
error prone, since you would have to access all the TCP sockets and other 
file handles that are in use by all the ReflectServers), or you would end up 
having to call do_once() without blocking on the sockets, which would be 
inefficient (you'd either get high message latency if you didn't call 
do_once() very often, or lots of wasted CPU cycles if you did call it very 
often)

> The reason why I ask is because I'm currently writing a custom server
> which needs to additionally process messages from other muscled
> servers.  That is, the custom server will be a muscled server and also
> be a client of other muscled servers.  It'll slurp in data from the
> other servers, and publish the data to itself.

If I understand you correctly, you want to run multiple ReflectServer objects 
from a single thread?  If so, I don't think that can be made to work very 
well -- the ReflectServer class is designed with the assumption that it will 
be in charge of driving its own event loop.  A better single-threaded 
solution for this case would be to have a single ReflectServer object, and 
make your separate "servers" actually be separate session objects that are 
attached to the single ReflectServer.

> I'd rather not create another process that just forwards the data,
> mainly because it seems wasteful -- as I'm already pushing more than
> 50,000 messages per minute, I'd like to trim down the amount of sending
> and receiving and duplicate data sitting around on various processes.

If you really need multiple ReflectServer objects (and it's not clear to me 
why you would need or want that, as opposed to a single ReflectServer object 
with multiple sessions, as described above), you could run each ReflectServer 
object in a separate thread of a single process and have them communicate 
with each other via SignalMessageIOGateways and shared message queues -- the 
MessageTransceiverThread class does essentially that, in fact.  However, I'd 
recommend against going multithreaded unless you really need to, because it 
does make things a good deal more complex and error-prone.  If you do end up 
trying it, let me know and I can probably give you some hints on how to go 
about it.

I hope that helps; if not, please describe more fully what your motivation 
towards wanting multiple ReflectServer objects is, and I will think about it 
some more.

-Jeremy

Other related posts: