Implementing a daemon and its interaction with a PHP application

    Actually, it’s rather a half-topic, half-question.
    I will describe the scheme that I got and I will ask the habray people for advice - how much such an implementation has the right to life and what should be improved in it =)
    Maybe someone will like this idea and they will adopt it - I do not mind =)

    Such a scheme I am used in two tasks, however, I will describe everything on the example of one.
    So, I have some online browser game project. The task was to write the fastest chat with the following properties:
    - low load created by chat on the server;
    - support for a large number of players;
    - the ability to work both in continuous and in normal (refresh) modes;
    - The ability to work with players for proxy servers.



    General scheme of work


    I decided to separate the processing of the message queue into a separate process - the chat daemon.
    Either a php script (in the case of refresh mode) or a CGI application written in C (for continuous mode) works with the client.
    In both cases, messages are received from the daemon and the client is sent a JS code that adds messages to the chat frame.
    In refresh mode, the request to this php script leaves every few seconds, the script downloads all messages that appeared after the last refresh and sends it to the client.
    In continuous mode, the CGI process starts, and in an infinite loop with a small delay checks the message queue for new ones. If they appear - immediately sends them to the client.

    Demon-Client Interaction Interface


    For the CGI application, the optimal option seemed to me to be the fastest version of the shared memory segment.
    The daemon at startup selects a shared memory segment and writes all the messages there.
    The structure that describes the message has a fixed size and a simple binary format. Therefore, to receive a message by its serial number in the queue is a simple task.
    The message queue is cyclical, after the queue is completely full - new messages begin to fill the queue first, overwriting the old messages. Also in this segment there are two values ​​at fixed offsets, showing the current indicators of the beginning and end of the queue.
    The CGI client connects this memory segment at startup and obviously reads data from there, almost instantly learning about new messages.
    The state of the race does not occur, because Only a daemon writes to a segment. Readers can be an unlimited number.

    Adding Messages to the Queue


    To add messages to the queue, client scripts connect via a UNIX socket to a daemon and send a specially formed data packet.

    The daemon creates several threads at startup and starts listening to the socket.
    Incoming connections distributes to threads in turn.
    Streams accept a command from a socket. If this is a command to add a message to the queue, they capture a mutex that controls the access to the message queue, and add it there.

    Implementation advantages


    The problem is solved =)
    Chat does not use non-standard ports - everything works through a web server, so chat can work behind hard corporate proxies.
    The load on the server from the chat is almost imperceptible.

    Cons of implementation


    Poor scalability, reckoning that the web server and daemon are running on the same machine.

    Conclusion


    This work scheme was run on production and did not cause any comments.
    However, perhaps it is not optimal - this is the best that came to mind =)
    I will be glad to hear your comments on this implementation option.
    If my implementation suddenly seems interesting to someone, I’m ready to talk about something in more detail, for example, go deeper into the application part of the chat (channels, filter, message formatting, commands) or the system part of the server implementation (with code examples).

    Also popular now: