Skip to content

Commit 22dfff4

Browse files
committed
Worker middleware
1 parent a73918b commit 22dfff4

File tree

6 files changed

+51
-13
lines changed

6 files changed

+51
-13
lines changed

bolt-worker/bolt/worker/admin.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class LostJobsCard(Card):
7171
text = "View" # TODO make not required - just an icon?
7272

7373
def get_description(self):
74-
delta = timedelta(seconds=settings.JOBS_LOST_AFTER)
74+
delta = timedelta(seconds=settings.WORKER_JOBS_LOST_AFTER)
7575
return f"Jobs are considered lost after {_td_format(delta)}"
7676

7777
def get_number(self):
@@ -179,7 +179,7 @@ class ListView(AdminModelListView):
179179
default_datetime_range = DatetimeRangeAliases.LAST_30_DAYS
180180

181181
def get_description(self):
182-
delta = timedelta(seconds=settings.JOBS_CLEARABLE_AFTER)
182+
delta = timedelta(seconds=settings.WORKER_JOBS_CLEARABLE_AFTER)
183183
return f"Jobs are cleared after {_td_format(delta)}"
184184

185185
def get_initial_queryset(self):

bolt-worker/bolt/worker/cli.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def _shutdown(signalnum, _):
6161

6262
@cli.command()
6363
def clear_completed():
64-
cutoff = timezone.now() - datetime.timedelta(seconds=settings.JOBS_CLEARABLE_AFTER)
64+
cutoff = timezone.now() - datetime.timedelta(seconds=settings.WORKER_JOBS_CLEARABLE_AFTER)
6565
click.echo(f"Clearing jobs finished before {cutoff}")
6666
results = (
6767
JobResult.objects.exclude(ended_at__isnull=True)
+5-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
JOBS_CLEARABLE_AFTER: int = 60 * 60 * 24 * 7 # One week
2-
JOBS_LOST_AFTER: int = 60 * 60 * 24 # One day
1+
WORKER_JOBS_CLEARABLE_AFTER: int = 60 * 60 * 24 * 7 # One week
2+
WORKER_JOBS_LOST_AFTER: int = 60 * 60 * 24 # One day
3+
WORKER_MIDDLEWARE: list[str] = [
4+
"bolt.worker.middleware.AppLoggerMiddleware",
5+
]

bolt-worker/bolt/worker/middleware.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from bolt.logs import app_logger
2+
3+
4+
class AppLoggerMiddleware:
5+
def __init__(self, run_job):
6+
self.run_job = run_job
7+
8+
def __call__(self, job):
9+
app_logger.kv.context["job_request_uuid"] = str(job.job_request_uuid)
10+
app_logger.kv.context["job_uuid"] = str(job.uuid)
11+
12+
job_result = self.run_job(job)
13+
14+
app_logger.kv.context.pop("job_request_uuid", None)
15+
app_logger.kv.context.pop("job_uuid", None)
16+
17+
return job_result

bolt-worker/bolt/worker/models.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def mark_lost_jobs(self):
9797
# In theory we could save a timeout per-job and mark them timed-out more quickly,
9898
# but if they're still running, we can't actually send a signal to cancel it...
9999
now = timezone.now()
100-
cutoff = now - datetime.timedelta(seconds=settings.JOBS_LOST_AFTER)
100+
cutoff = now - datetime.timedelta(seconds=settings.WORKER_JOBS_LOST_AFTER)
101101
lost_jobs = self.filter(
102102
created_at__lt=cutoff
103103
) # Doesn't matter whether it started or not -- it shouldn't take this long.
@@ -183,6 +183,22 @@ def convert_to_result(self, *, status, error=""):
183183

184184
return result
185185

186+
def as_json(self):
187+
"""A JSON-compatible representation to make it easier to reference in Sentry or logging"""
188+
return {
189+
"uuid": str(self.uuid),
190+
"created_at": self.created_at.isoformat(),
191+
"started_at": self.started_at.isoformat() if self.started_at else None,
192+
"job_request_uuid": str(self.job_request_uuid),
193+
"job_class": self.job_class,
194+
"parameters": self.parameters,
195+
"priority": self.priority,
196+
"source": self.source,
197+
"retries": self.retries,
198+
"retry_attempt": self.retry_attempt,
199+
"unique_key": self.unique_key,
200+
}
201+
186202

187203
class JobResultQuerySet(models.QuerySet):
188204
def successful(self):

bolt-worker/bolt/worker/workers.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
from functools import partial
88

99
from bolt.db import transaction
10-
from bolt.logs import app_logger
10+
from bolt.runtime import settings
1111
from bolt.signals import request_finished, request_started
12+
from bolt.utils.module_loading import import_string
1213

1314
from .models import Job, JobRequest, JobResult, JobResultStatuses
1415

@@ -166,17 +167,18 @@ def process_job(job_uuid):
166167
job.source,
167168
)
168169

169-
app_logger.kv.context["job_request_uuid"] = str(job.job_request_uuid)
170-
app_logger.kv.context["job_uuid"] = str(job.uuid)
170+
middleware_chain = lambda job: job.run()
171171

172-
job_result = job.run()
172+
for middleware_path in reversed(settings.WORKER_MIDDLEWARE):
173+
middleware_class = import_string(middleware_path)
174+
middleware_instance = middleware_class(middleware_chain)
175+
middleware_chain = middleware_instance
176+
177+
job_result = middleware_chain(job)
173178

174179
# Release it now
175180
del job
176181

177-
app_logger.kv.context.pop("job_request_uuid", None)
178-
app_logger.kv.context.pop("job_uuid", None)
179-
180182
duration = job_result.ended_at - job_result.started_at
181183
duration = duration.total_seconds()
182184

0 commit comments

Comments
 (0)