Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are Django signals thread safe?

Tags:

django

signals

If I will disconnect and then connect some signals in single thread context will that affect signal pool used by other threads?

UPDATE
I'll try to be more specific.

I'm using post_save and pre_delete signals for few senders that trigger fulltext engine reindexing for a specific model (one particular model) which is a main source of content for fulltext engine.

Reindexing is done via Celery tasks and signal handlers simply dispatch reindexing tasks to broker (in my case Redis).

Some post_save signals should not trigger reindexing (that is - should not dispatch Celery tasks, pre_delete should always trigger reindexing) as some of model changes are irrelevant to fulltext engine content (i.e. status changes, timestamps changes and few others). I'm not quite able to verify update_fields in handler kwargs for every case because, from what I've observed, admin site save operations do not specify those.

I'm using a custom context manager which disconnects reindexing handlers from post_save signals for specific senders, yields control back to invoking piece of code, then save operation on model is executed and when the control is passed back to context manager all reindexing handlers are being reconnected to post_save signals for specific senders.

I want to be sure this disconnect/connect routine in context manager executed in single thread context will not affect other threads (that is - all signals disconnected in single thread context will be still connected in other threads).

Thanks! unkletee

like image 565
unkletee Avatar asked Jan 03 '14 15:01

unkletee


People also ask

Is Django thread-safe?

Note that the Django ORM is explicitly thread-safe. There are multiple references in the documentation about threaded operation.

Should you use Django signals?

The only reason to use signalsOnly use signals to avoid introducing circular dependencies. If you have two apps, and one app wants to trigger behaviour in an app it already knows about, don't use signals. The app should just import the function it needs and call it directly.

Are Django signals asynchronous?

To answer directly: No. It's sync.

How do signals work in Django?

Django includes a “signal dispatcher” which helps decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place.


1 Answers

If your code looks like this:

@contextmanager
def disable_signal():
   try:
      post_save.disconnect(your_signal)
      yield None
   finally: 
      post_save.connect(your_signal)

This is not thread safe because we are changing a global variable. https://docs.python.org/3/library/contextlib.html#reentrant-context-managers

Note also that being reentrant is not the same thing as being thread safe. redirect_stdout(), for example, is definitely not thread safe, as it makes a global modification to the system state by binding sys.stdout to a different stream.

like image 148
kjaw Avatar answered Nov 23 '22 23:11

kjaw