PyroX has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to plan this out, and come up with some code ideas.

This diagram shows what I want to accomplish:
explain.jpg

So basically, I want to have a web client, be it cgi, php, java, asp, whatever; connect to the server process and get an id and start a child daemon to keep as its own.

Then the web client will talk to the child which maintains a connection to a server somewhere else and recieves / sends data back and forth. The received data will be stored in a buffer or que for deliver back to the web client when it connects.

Is this laid out efficiently or should I always connect to the main daemon and have it talk to the children? Anyone have an existing project like this that could help guide me, or some code examples?

Is it possible to talk to a process that is already running without using a port?

Thanks for any and all help, no matter how big or little.

Replies are listed 'Best First'.
Re: Daemon - Child - Client - Server
by l2kashe (Deacon) on Feb 14, 2003 at 20:18 UTC
    Basically this is a similar model of running that software uses often. One very close to it would be Apache for example.

    When you fork off a child, it inherits all the parents handles, so what happens with the Apache example is
    1) Main daemon listens on port 80
    2) request comes in
    3) Parent forks child to deal with request
    3a) Child inherits all open filehandles and variables
    4) Parent goes back to listening for requests
    4a) Child processes request
    5a) Child returns results
    6a) Child wait x time prior to telling the Parent it is done with said request

    While this isn't exactly technically accurate as to how Apache itself does it (as it maintains a pool of children to do its work, and only spawns more if its overloaded), its close enough for comparison.

    Questions:
    1) Is it worth it to queue the data up, or should you be processing real time streams?
    2) How many "clients" are we talking about?
    3) How far apart "logically" as well as "physically" are the "clients" and "servers"?
    4) What is an acceptable timeout for client->server, server->client, server->server communication?

    Yes it is possible to talk to a running process, provided the process has opened a 'socket' to deal with I/O. A socket can be a connection to a file, connection to the network stack, connection to a fifo or named pipe (which are really files, but we will ignore that for a sec and treat them differently), etc..

    Named pipes are kinda cool. Alot of X applications make use of fifos in the /tmp or /var/tmp directory. Basically there is this handle they check, if there is data in the handle they slurp it in and process it, if not they go back to what they were doing and check back again later.

    Personally I think your design is fine, and there are plenty of examples of forking servers, which is a fine search string to Super Search or Google for.

    Hope that helps, and happy hacking

    /* And the Creator, against his better judgement, wrote man.c */
      The web client may check back at any time between 5 seconds and 20 minutes, grab the que or buffered messages or actions and process them.

      The child needs to maintain the connection to the 3rd party server at all times until the web client hangs up.

      Initially we are talking about maybe 5 - 10 clients maximum. Later I would like to expand that to 25 or so.

      Named Pipes, I will be looking into the possibility of using that. I guesd files would be acceptable as well, the child could just amintain a file with the buffer and the web client can work with the file, this of course adds another component to the equation, but maybe less complexity.

      The 3rd party server is not very close, not local lan, not wan, but external to the network all-together. A timeout will not really be needed after connection, the child could notify the web client of the last buffer refresh and/or wether or not a update is needed. The only timeout here would be if the initial connection fails, or is lost later. Long periods of no data from the child is a possibility of course.

      I had looked at some postings here on perl web server daemons that fork to a child, and will probably start with that.

      Thanks for your help so far, everyone. All good info.
Re: Daemon - Child - Client - Server
by l2kashe (Deacon) on Feb 14, 2003 at 20:52 UTC
    On another note, you could use something I'm thinking as a cookie/token to maintain where a given client is within a given transaction. Then keep data (whether in FIFOs, DBs, or plain files) on what needs to go where based on the token. This could alleviate some issues, as you move to a state machine as opposed to dealing strictly with transactions.

    Thought process: Client connects if client->token { check datasource(token); if send_to_client { send_to_client clear_data_set } if client->new_cmd { do_something } } else { client->token(new); if client->new_cmd { do_something } }
    Then maintain a seperate process which sits and checks for server->server communication requests, handles that, and updates the data source appropriatly.

    A breakdown that way seems slightly less complicated to me, while residing within what you want to do. Also you can update the client or server piece without a major rewrite of the entire app


    /* And the Creator, against his better judgement, wrote man.c */
Re: Daemon - Child - Client - Server
by dws (Chancellor) on Feb 14, 2003 at 21:40 UTC
    Anyone have an existing project like this that could help guide me, or some code examples?

    merlyn has a two part article that shows how to set up a separate, semi-persistent server session using HTTP::Daemon. The client connects to the web server, which forks a session process and redirects the client to it. The client then communicates with the session process until the session is done or the session times out.

Re: Daemon - Child - Client - Server
by tall_man (Parson) on Feb 14, 2003 at 20:12 UTC
    The first stage of your idea, having a cgi script talk to a daemon process and start up another process, is no problem. I've used IO:Socket for that purpose several times.

    The real trick is getting updates back to your page asynchrononously as the child process generates them. Yes, you could have them happen only when the browser user hits a refresh button, but that's not terribly effective.

    Without using something active in the page, such as a java applet or perl plus plugin I don't know a good solution.

    Update: There are all sorts of ways to communicate to a running process on the same machine without a socket. You could use named pipes, signals, or write to a regular file it is monitoring. If it has a GUI, you can generate Windows events (on Windows) or X windows events (on Linux).

      The real trick is getting updates back to your page asynchrononously as the child process generates them. Yes, you could have them happen only when the browser user hits a refresh button, but that's not terribly effective.
      What about <meta/>-refresh?
      AFAIK every browser understands this. Sure enough, it's just kind of a mechanized button-press and occurs independent of data-changes/-updates, but its a viable solution.

      regards,
      tomte


      Edit: added second sentence.

Re: Daemon - Child - Client - Server
by perrin (Chancellor) on Feb 14, 2003 at 20:14 UTC
    Offhand, this sounds like an overly complex solution, but it's hard to give you advice without knowing what you're trying to accomplish.

    I suggest you read this and this.