mercredi 30 juin 2021

fastAPI manage workers with Background tasks

I'm working in a FastAPI backend with some peculiarities... Let me explain firstly the usual workflow of the app:

  1. The user introduces an IP of the system that wants to track.
  2. The backend receives it and creates an object (an instance of a class) that starts a loop (typical run method) in a FastAPI BackgroundTasks to store the data periodically in a database.
  3. When the user wants to stop tracking that system just clicks "Stop". So the backend finishes that loop and the BackgroundTasks ends.

As it was supposed to be a small app, the objects where stored in a pythons global dict like this:

{
 "X.X.X.X": new Handler (a new instance of the class),
 "Y.Y.Y.Y": new Handler,
 ...
}

And I could easily grab the objects to control them.

The issue is that I'm tracking a bigger number of systems and the systems starts to go slow. So I decided to use the workers option of uvicorn to see if I could fix the issue (e.g. having 4 processes with 6 threads). However, when Uvicorn starts num_workers new multiprocessing.Process and the requests are responded by one of them, you may not find the object in the global dict (after all Processes are not Threads...).

So I tried using a multiprocessing.managers.SyncManager and "creating" a kind of cache memory. However, when I try to store the object instance it says cannot pickle '_thread.lock' object. I'm not pretty sure if it is not possible to do what I wanted or what... (Sharing python objects across multiple workers)

I've also tried aiocache what I was creating new instances of the Caches so didn't work either.

I've also tried with guvicorn and the --preload cmd option but same result...

I don't know if it could be possible to do some kind of routing with a middleware so I could search which process has in its dictionary the IP's object needed or something like that...

In conclusion, I'm asking for advice... how could I deal with this problem?

P.D: sorry for the long text!

Thanks!!




Aucun commentaire:

Enregistrer un commentaire