Django: What exactly are signals good for?
Asked Answered
S

4

9

I have a tough time understanding how signals work into my application (and how they work period). These are three areas where I assume they would apply (with my current knowledge):

  1. Send XML to a remote server for reporting (after a transaction is complete).
  2. Re size an image and upload the thumbnail to S3 after a user uploads it.
  3. Delete old images from S3 after a user deletes an image object from his account.

Am I totally off base (I feel I might be). Am I getting signals and multi threading mixed up? If so, do they compare in there application? Are they only for decoupling? Also, what's the deal with making sure you instantiate them early and don't use a local function (because they'll get garbage collected)? Can someone elaborate on that? Should I put them all in request Middleware so that I don't have to worry?

Soso answered 19/1, 2010 at 21:26 Comment(2)
I don't understand your reference to multi threading. What's the point?Perichondrium
@Andrea Zilio See comments on answer 1Soso
P
18

Django Signals are a way to perform an action A in response to an event E.

In a unreal world you can avoid using signals by modifying the code where the event E occurs and appending the code to perform the action A.

The problem is that doing so you loose maintainability, readability and a lot of other software engineering adjectives :)

Signals allow you to do the same thing indipendently from where or how the event E occurs and so doing so in a clever way that allow maintanability, readability, etc...

Yes, I think that saying that Signals are useful to enable decoupling is really true.

(You also mentioned multi threading. If you did so because you think signals are good because they are executed concurrently and so quickly... Well... I don't know if they are concurrently executed but anyway I really don't think this is the point for what django signals are useful for)

An example of a good way of taking advantage of Signals is about the fact that when you want to store other information to an user in django you have to use Userprofiles. In this case, the documentation itself, tell you that it may be convenient to register a signal in response to any creation of new users just to add to the new created users an empty user profile.

Perichondrium answered 19/1, 2010 at 21:35 Comment(7)
Django signals are definitely dispatched synchronously.Almanza
@Ignacio My intention was not to say that signals are concurrently executed, but just to try to imagine why multi threading was mentioned in the question... I didn't know how they were handled. Now I do. Thanks Ignacio ;)Perichondrium
Would you consider the 3 tasks in my list as good candidates to perform via signals?Soso
The reason I mentioned multi threading is not for the concurrency benefit, but rather for the case where the user sees the "thank you" page and it's done loading but things are still going on in the server. Is this possible?Soso
Task 1, not really. Just put the code to upload it after the code for the transaction. Task 2, sure. But you might be better off farming that off to a separate process altogether. Task 3, possibly, although using the word "delete" in a task can lead to racy code if not done properly.Almanza
@orokusaki: Not directly via signals, since signals are dispatched synchronously. Instead dispatch the processing to another process.Almanza
@Soso I think that tasks 2 and 3 are good candidates to be performed via signals. Maybe in task 2 you can spend a lot of time for the upload and so, since signals are synchronously executed, you may consider to do so asynchronously from the request (otherwise the user has to way for the image to be uploaded to S3 too)... It may depend on the size of these images. With respect to the first task... Well, I have not understood what it should do...Perichondrium
S
5

Here is an example that may help.

Suppose you need to perform some action when a model instance is saved. However, this action has got nothing to do with the model or model instance itself directly. Therefore it makes little sense to put the code for your action in a save() method on the model. It would cause unnecessary code coupling and clutter. Instead you can create a signal handler somewhere else in your application (or even in another application) where it makes more sense.

Stiltner answered 19/1, 2010 at 21:57 Comment(0)
H
3

I would perform Tasks 2 and 3(the images stuff) with something like an asynchronous task queue, like Celery

That's similar to multithreading.

Heteroplasty answered 5/10, 2011 at 23:23 Comment(0)
C
0

Signals are NOT asynchronous (NOT running in concurrent or parallel way)

That's why they are NOT so useful for things like you mentioned:

  • File upload or file post-processing
  • Reports generation
  • Any other long term operations (requests to another servers, ET)

It is better Celery workers that can do long term operations in really asynchronous way.

But they are still valuable in a few limited scenarios

  • Extending the functionality of a third-party library. If you're using an app with models where you don't control the code, signals are a more robust alternative to monkey-patching for taking specific actions on save or delete.
  • Delete signals work on the delete queryset method. If you'd like the same actions to happen on both single object and queryset deletes, a signal is probably your best bet.
    Note: Due to the way the SQL is generated, this does not apply to the update queryset method (with save signals). Another frequent source of confusion/bugs.
  • When you need to apply the same signal handler to many models. If you just have a few, I'd still favor overriding the save/delete method and calling a shared function. For more than a few, copy/pasting the save method everywhere becomes more error-prone and signals look like a better option.
  • Avoiding tight cross-application dependencies. If you need to cross application boundaries, especially when the application may be used in multiple projects, signals may be better for looser coupling between the apps. Be careful with this one though. Use it because you need to, not because you think you might want it in the future.

These cases and some examples for them you can find in this topic.

Commonality answered 24/9, 2019 at 9:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.