Is async channel the best way to communicate between async tasks?

Hello everyone! I'm creating an open-source SystemD daemon service for providing high availability to network backend applications. The idea is simple: you describe your services in a configuration file, and buzz-operator reads it and runs your service. It performs healthchecks, restarts your service if it exits with an error, performs rolling updates, and runs scripts for updating other configurations. For example, if you run multiple instances behind nginx and upload a new version to VPS, the daemon will gradually replace all instances, run a script to update the nginx config, and reload nginx.

I have several types here:

  • ServiceUnit - represents one instance of a single service
  • ServiceBunch - represents multiple instances of a single service
  • ServiceController - represents multiple bunches

I created all of them in an asynchronous manner, and I use the tokio runtime for this purpose. ServiceUnit runs and waits for one of two events: exit from the process or a message from ServiceBunch to terminate this unit. Anyway, if the process is terminated, ServiceUnit returns control.

ServiceBunch runs multiple units and waits for all of them. Also, when a bunch creates one unit, it gives the receiver part of an async channel to send a termination message. ServiceController also communicates between every bunch using tokio::sync::mpsc::channel.

In my main function, I listen on a Unix socket for commands from the user (start service, stop service, reload, etc.) and send messages to the controller over the channel again. When I created this, I didn't find any option to communicate between tasks except channels because an async task wants to own its values. I'm not very experienced with manual Future implementation, but I know how Pin and stuff works.

Can you please advise me if there are more optimal options, or if using only channels is totally fine?

Channels are fine.

You can read more about using channels here:

2 Likes