django-after-response icon indicating copy to clipboard operation
django-after-response copied to clipboard

This project is not thread safe

Open agronick opened this issue 8 years ago • 2 comments

The function_queue variable is shared between all the threads on a process. If thread 1 adds something to the queue and then does some more processing and thread 2 comes along and finishes, even if it didn't add anything to the queue, it will process thread 1's function while thread 1 is still running.

You should replace function queue with a method that will pull the list from the threading.local and create it if it does not exist. Do not just put the variable in threading.local and leave it as a global variable. Then you'll just be sharing the thread local with all the other processes.

It should be something like this:

import threading
threadlocal = threading.local()    

def function_queue():
  queue = getattr(threadlocal, 'function_queue', None)
  if v is None:
    queue = []
    setattr(threadlocal, 'function_queue', queue)
  return queue

agronick avatar Apr 15 '17 03:04 agronick

Would deque be a good idea? https://docs.python.org/3.6/library/collections.html#collections.deque

kregoslup avatar Jan 02 '18 14:01 kregoslup

That might give you a speed increase. I think most people will only add a few functions so you'll see hardly any speed increase vs a list. It won't give you thread safety. You can use thread locals or you could add the fuctions to a property on the request object. That way even if people add functions from mutiple threads they'll be accociated with the request. I think hardly anyone would set callbacks from multiple threads though and you would have to start passing the request around to do that.

agronick avatar Jan 03 '18 23:01 agronick