Suppose your service needs to expose the ability handle the lifecycle of some in-deterministically long living process. Say it needs to spawn, list and stop processes.
The naive solution typically includes some utilisation of context.WithCancel
, where a centralised map[processID]context.CancelFunc
would host the means to cancel processes running on a detached goroutine*.
The problem here is that this CancelFunc
map centralises process state, prohibiting horizontal scaling of the service as each service would own the means of cancelling different process. I personally ran into this problem. So this serves as a playground to explore alternative methods.
Basically pushing the responsibility of tracking process state to the database. For each process, a goroutine is spawned, which concurrently polls for process cancel requests and runs the process. Use of nginx
for some simple load balancing.
docker compose up --scale process-manager=12
* see commit 5581706feca5f183198ec148042a5ea061ae9771
as an example