[muscle] Re: ReflectServer::ServerProcessLoop

  • From: Jeremy Friesner <jaf@xxxxxxxxxxxx>
  • To: muscle@xxxxxxxxxxxxx
  • Date: Tue, 24 Aug 2004 18:39:47 -0700

On Tuesday 24 August 2004 17:55, Wilson Yeung wrote:
> I don't think I was very clear.  What I want to do is:
>
> 1. Run a stock muscled server, say muscled1.
>
> 2. In another program, create a muscle client that is connected to
> muscled1.  Whenever a message is delivered from muscled1 to the client,
> parse the message and massage it, and insert it into myCustomMuscled
> server.  The custom server, myCustomMuscled is in the same process
> space as the client.

Okay, so we have a server process ("muscled1"), and a client process that 
contains both your client program and a myCustomMuscled server.

If your client program is simple (i.e. it has no GUI or other separate 
event-loop API of its own) then your client could be implemented as a session 
object that is attached to the myCustomMuscled server object.  Your 
myCustomMuscled server could add this client-session object to itself during 
startup, by calling ReflectServer::AddNewConnectSession(), so that the 
client-session object would initiate a TCP connection to muscled1.  That 
would be a very simple, easy solution that wouldn't require any 
multithreading or event-loop hackery.

If your client code is such that it requires its own separate event loop (and 
there is no easy way to modify it so that it doesn't), then probably the 
multithreaded solution is the best way to handle the problem.  That is, your 
client code would run in the main thread, and as part of its startup it would 
spawn off a separate thread that runs your myCustomMuscled server.  If you 
prefer this solution, the easiest way to implement it is to subclass the 
MessageTransceiverThread class, since a MessageTransceiverThread object 
spawns a new thread and runs a ReflectServer event-loop inside the spawned 
thread.  You will probably want to override the MessageTransceiverThread's 
CreateReflectServer() method, and/or its CreateSupervisorSession() and 
CreateDefaultSessionFactory() methods as well, so that the spawned thread 
will use your myCustomMuscled logic instead of the default ReflectServer 
logic.

> Because ServerProcessLoop never returns, how would I call the client's
> DoInput() method to process incoming messages?

I think it's better not to try to call the I/O methods manually yourself, but 
rather find a way to use the normal ServerProcessLoop() event-loop, so that 
they are called for you by the MUSCLE code.  Hopefully one of the methods I 
described above will work for you.

> You're right about the do_once() thing not being very nice ... you're
> absolutely right that unnecessary latency would be introduced.  Perhaps
> the solution is to provide a means of pulling out the file descriptor
> sets, and whatever other mechanism is required to feed relevant file
> descriptors back to the ReflectServer.  Then the application writer can
> choose whatever form of select or select equivalent they want to use.

One of the goals of the MUSCLE API was/is to move the select() hassles back 
behind the scenes, so that the application writer doesn't have to worry about 
them.  Re-exposing all of that would be a step backwards IMHO.

-Jeremy

Other related posts: