Search code examples
rustprocessipcdaemonchannel

What's the most idiomatic way to implement "live communication" with a process?


I have a program that runs in the background without any intervention.

However, I'd like to provide some control over running instances. Usage might look something like this:

$ foo start
# an instance starts running in the background
$ foo refresh bar,baz
# the running instance does something with bar and baz

What's the typical way of implementing something like this? Is there a way to share channels between instances somehow? How do I locate the existing instance in the first place?


Solution

  • A typical way for this would be to use a client-server approach.

    foo start can be starting a server. To start it in background as a daemon from the macOS shell:

    pkill foo && nohup foo start > out.log 2>&1 &
    

    or simply (in some cases could be enough):

    foo start &
    

    On Linux it could be configured as a systemd service, init script or a cron job.

    foo refresh can be a client that sends a request to the running daemon instance.

    If you only need a one-way communication one typical way to do this is to use HTTP (e.g. using warp for the server and reqwest for the client). In this case a way to locate the running instance would be to define a constant shared port number, e.g. 12345. Then the server can listen on "localhost:12345", and the client can request "http://localhost:12345/refresh?ids=bar,baz".

    If you don't want an overhead of the libraries, and your communication protocol is as simple as you describe, the simplest way would be to use a shared file. In this case a way to locate the running instance would be to define a constant shared file name, e.g. "/var/run/foo/request.txt". Then the client writes to this file a line "refresh bar,baz", and the server detects the change, reads it and does something (potentially output the response to the same file, or some other shared file).