The work done in #146 added an enhanced UI component for determining if the Celery workers are available. Unfortunately, the call to app.inspect() is synchronous, and takes upwards of 5 seconds to return. It is not a desirable user experience to see the loading spinner for that long each time a page loads!
We will eventually need the ability to run scans on a schedule. a package like django-celery-beat is well suited to use the existing Celery functionality to periodically run things. This ticket will add support for that, and the first interval-based task: the resource scanner.
Periodic Task Configuration
A new configuration will be added to the celery.py file to configure the new periodic task.
app.conf.beat_schedule = {
# Execute the ping task every minute
'celery-worker-ping-1min': {
'task': 'worker.tasks.ping_task',
'schedule': crontab(minute='*/1'),
},
}
Celery Beat Worker
The Celery management command will need to be augmented to start and stop the beat functionality. In addition, the initialize_app management command will need to be updated to support beat processing.
Worker Resource Tracking
A new model will be added to track what workers are available to Celery during the application startup. It's these workers that will be checked in the new worker resource monitor task.
class Worker(models.Model):
celery_name: models.CharField()
last_ping: models.DateTimeField()
available: models.BooleanField()
Detecting Workers
Within the WorkerConfig class, the ready(self) method will be overridden in order to perform one-time initialization during application startup. The pseudo-code for ready() is as follows:
from chirps.celery import app
def ready(self):
# Delete all of the previous workers
Worker.objects.all().delete()
# Query Celery to find out what workers are available
celery_inspection = app.control.inspect()
celery_statuses = celery_inspection.stats()
The call to celery_inspection.stats() will return information about all of the workers that are currently running. The contents of the response are a dictionary, keyed by the ID of the worker.
A new tasks.py file will be added to the worker application. Within it, a function will build a list of names from the Worker table and then issue a ping() operation to verify they are online.
Pseudocode
from chirps.celery import app
from django.utils import timezone
def ping_task():
celery_inspection = app.control.inspect()
for worker in Worker.objects.all():
result = celery_inspection.ping(destination=[worker.celery_name])
if result is None:
worker.available = False
else:
worker.last_ping = timezone.now()
worker.save()
Worker status view
So with the new periodic task in place, the view which fetches the status of the workers will now query the database instead of querying the worker itself.
The work done in #146 added an enhanced UI component for determining if the Celery workers are available. Unfortunately, the call to
app.inspect()
is synchronous, and takes upwards of 5 seconds to return. It is not a desirable user experience to see the loading spinner for that long each time a page loads!We will eventually need the ability to run scans on a schedule. a package like
django-celery-beat
is well suited to use the existing Celery functionality to periodically run things. This ticket will add support for that, and the first interval-based task: the resource scanner.Periodic Task Configuration
A new configuration will be added to the
celery.py
file to configure the new periodic task.Celery Beat Worker
The Celery management command will need to be augmented to start and stop the beat functionality. In addition, the
initialize_app
management command will need to be updated to support beat processing.Worker Resource Tracking
A new model will be added to track what workers are available to Celery during the application startup. It's these workers that will be checked in the new worker resource monitor task.
Detecting Workers
Within the
WorkerConfig
class, theready(self)
method will be overridden in order to perform one-time initialization during application startup. The pseudo-code forready()
is as follows:The call to
celery_inspection.stats()
will return information about all of the workers that are currently running. The contents of the response are a dictionary, keyed by the ID of the worker.Worker Ping Task
A new
tasks.py
file will be added to theworker
application. Within it, a function will build a list of names from theWorker
table and then issue aping()
operation to verify they are online.Pseudocode
Worker status view
So with the new periodic task in place, the view which fetches the status of the workers will now query the database instead of querying the worker itself.