Signals

Signals are events broadcasted when something happens in Spinach, like a job starting or a worker shutting down.

Subscribing to signals allows your code to react to internal events in a composable and reusable way.

Subscribing to signals

Subscribing to a signal is done via its connect decorator:

from spinach import signals

@signals.job_started.connect
def job_started(namespace, job, **kwargs):
    print('Job {} started'.format(job))

The first argument given to your function is always the namespace of your Spinach Engine, the following arguments depend on the signal itself.

Subscribing to signals of a specific Spinach Engine

As your application gets bigger you may end up running multiple Engines in the same interpreter. The connect_via decorator allows to subscribe to the signals sent by a specific Spinach Engine:

from spinach import Engine, MemoryBroker, signals

foo_spin = Engine(MemoryBroker(), namespace='foo')
bar_spin = Engine(MemoryBroker(), namespace='bar')

@signals.job_started.connect_via(foo_spin.namespace)
def job_started(namespace, job, **kwargs):
    print('Job {} started on Foo'.format(job))

In this example only signals sent by the foo Engine will be received.

Available signals

spinach.signals.job_started = SafeNamedSignal "job_started"

Sent by a worker when a job starts being executed.

Signal handlers receive:

  • namespace Spinach namespace
  • job Job being executed
spinach.signals.job_finished = SafeNamedSignal "job_finished"

Sent by a worker when a job finishes execution.

The signal is sent no matter the outcome, even if the job fails or gets rescheduled for retry.

Signal handlers receive:

  • namespace Spinach namespace
  • job Job being executed
spinach.signals.job_schedule_retry = SafeNamedSignal "job_schedule_retry"

Sent by a worker when a job gets rescheduled for retry.

Signal handlers receive:

  • namespace Spinach namespace
  • job Job being executed
  • err exception that made the job retry
spinach.signals.job_failed = SafeNamedSignal "job_failed"

Sent by a worker when a job failed.

A failed job will not be retried.

Signal handlers receive:

  • namespace Spinach namespace
  • job Job being executed
  • err exception that made the job fail
spinach.signals.worker_started = SafeNamedSignal "worker_started"

Sent by a worker when it starts.

Signal handlers receive:

  • namespace Spinach namespace
  • worker_name name of the worker starting
spinach.signals.worker_terminated = SafeNamedSignal "worker_terminated"

Sent by a worker when it shutdowns.

Signal handlers receive:

  • namespace Spinach namespace
  • worker_name name of the worker shutting down

Tips

Received objects

Objects received via signals should not be modified in handlers as it could break something in Spinach internals.

Exceptions

If your receiving function raises an exception while processing a signal, this exception will be logged in the spinach.signals logger.

Going further

Have a look at the blinker documentation for other ways using signals.