Search code examples
c#cachingredismicroservicesdistributed

c# Multi-Instance Microservice - Canceling a task


Currently I have a long running task implemented as a singleton.

To ensure future scalablity I want this task to work in a multi-instance environment and ensure it only runs once.

I started implementing the IDistributedCache interface to get the status of the task from any instance of my service.

Now I figured, maybe I want to be able to cancel my task ... But I can't just throw the cancelationToken into the cache I assume.

Is there some standard approach to this problem similar to the 'fake' IDistributedCache Implementation that lets me prepare my code for a future Redis implementation.

  services.AddDistributedMemoryCache();

Solution

  • What you are actually asking for is a distributed lock which can make sure, a certain thing runs only once across all your service instances.

    Distributed locking can be implemented with Redis and is even documented here with examples and libraries implementing it.

    The problem is that distributed locking gets more and more complex to do depending on how much guarantees you expect for the lock. The simplest lock would be writing a key in one redis instance and each instance checks if the key exists. But there are many edge cases which would still let multiple instance through and your task would run multiple times anyways.

    Anyways, I'd suggest to use events instead with something like Azure Service Bus which, on the service level, without you having to implement anything, can deliver an event either to multiple subscribers or only to one. This will give you a way easier way to run something only once, 100% of the time.

    Again, it depends on how much you have to rely on it running only once and what you are doing, if you actually need that complexity or not.