Switch BackgroundJob to regular methods

Instead of using a class method for run(), a regular method is used for
this purpose. This gives the possibility to add more convenience methods
in the future, e.g. for interacting with the job object or for logging,
as implemented for scripts.
This commit is contained in:
Alexander Haase 2024-07-25 16:38:42 +02:00
parent 4c2ba0959f
commit c047bf4441
5 changed files with 22 additions and 24 deletions

View File

@ -19,9 +19,8 @@ class MyTestJob(BackgroundJob):
class Meta: class Meta:
name = "My Test Job" name = "My Test Job"
@classmethod def run(self, *args, **kwargs):
def run(cls, job, *args, **kwargs): obj = self.job.object
obj = job.object
# your logic goes here # your logic goes here
``` ```
@ -62,8 +61,7 @@ class MyHousekeepingJob(BackgroundJob):
class Meta: class Meta:
name = "Housekeeping" name = "Housekeeping"
@classmethod def run(self, *args, **kwargs):
def run(cls, job, *args, **kwargs):
# your logic goes here # your logic goes here
``` ```
```python title="__init__.py" ```python title="__init__.py"

View File

@ -17,9 +17,8 @@ class SyncDataSourceJob(BackgroundJob):
class Meta: class Meta:
name = 'Synchronization' name = 'Synchronization'
@classmethod def run(self, *args, **kwargs):
def run(cls, job, *args, **kwargs): datasource = DataSource.objects.get(pk=self.job.object_id)
datasource = DataSource.objects.get(pk=job.object_id)
try: try:
datasource.sync() datasource.sync()

View File

@ -26,14 +26,12 @@ class ScriptJob(BackgroundJob):
# where jobs other than this one are used. Therefore, it is hidden, resulting in a cleaner job table overview. # where jobs other than this one are used. Therefore, it is hidden, resulting in a cleaner job table overview.
name = '' name = ''
@staticmethod def run_script(self, script, request, data, commit):
def run_script(script, job, request, data, commit):
""" """
Core script execution task. We capture this within a method to allow for conditionally wrapping it with the Core script execution task. We capture this within a method to allow for conditionally wrapping it with the
event_tracking context manager (which is bypassed if commit == False). event_tracking context manager (which is bypassed if commit == False).
Args: Args:
job: The Job associated with this execution
request: The WSGI request associated with this execution (if any) request: The WSGI request associated with this execution (if any)
data: A dictionary of data to be passed to the script upon execution data: A dictionary of data to be passed to the script upon execution
commit: Passed through to Script.run() commit: Passed through to Script.run()
@ -80,10 +78,9 @@ class ScriptJob(BackgroundJob):
# Update the job data regardless of the execution status of the job. Successes should be reported as well as # Update the job data regardless of the execution status of the job. Successes should be reported as well as
# failures. # failures.
finally: finally:
job.data = script.get_job_data() self.job.data = script.get_job_data()
@classmethod def run(self, data, request=None, commit=True, **kwargs):
def run(cls, job, data, request=None, commit=True, **kwargs):
""" """
Run the script. Run the script.
@ -93,7 +90,7 @@ class ScriptJob(BackgroundJob):
request: The WSGI request associated with this execution (if any) request: The WSGI request associated with this execution (if any)
commit: Passed through to Script.run() commit: Passed through to Script.run()
""" """
script = ScriptModel.objects.get(pk=job.object_id).python_class() script = ScriptModel.objects.get(pk=self.job.object_id).python_class()
# Add files to form data # Add files to form data
if request: if request:
@ -107,4 +104,4 @@ class ScriptJob(BackgroundJob):
# Execute the script. If commit is True, wrap it with the event_tracking context manager to ensure we process # Execute the script. If commit is True, wrap it with the event_tracking context manager to ensure we process
# change logging, event rules, etc. # change logging, event rules, etc.
with event_tracking(request) if commit else nullcontext(): with event_tracking(request) if commit else nullcontext():
cls.run_script(script, job, request, data, commit) self.run_script(script, request, data, commit)

View File

@ -27,13 +27,19 @@ class BackgroundJob(ABC):
class Meta: class Meta:
pass pass
def __init__(self, job):
"""
Args:
job: The specific `Job` this `BackgroundJob` helper class is executing.
"""
self.job = job
@classproperty @classproperty
def name(cls): def name(cls):
return getattr(cls.Meta, 'name', cls.__name__) return getattr(cls.Meta, 'name', cls.__name__)
@classmethod
@abstractmethod @abstractmethod
def run(cls, *args, **kwargs): def run(self, *args, **kwargs):
""" """
Run the job. Run the job.
@ -51,7 +57,7 @@ class BackgroundJob(ABC):
""" """
try: try:
job.start() job.start()
cls.run(job, *args, **kwargs) cls(job).run(*args, **kwargs)
job.terminate() job.terminate()
except Exception as e: except Exception as e:

View File

@ -10,8 +10,7 @@ from core.choices import JobStatusChoices
class TestBackgroundJob(BackgroundJob): class TestBackgroundJob(BackgroundJob):
@classmethod def run(self, *args, **kwargs):
def run(cls, *args, **kwargs):
pass pass
@ -54,9 +53,8 @@ class BackgroundJobTest(BackgroundJobTestCase):
class ErroredBackgroundJob(TestBackgroundJob): class ErroredBackgroundJob(TestBackgroundJob):
EXP = Exception('Test error') EXP = Exception('Test error')
@classmethod def run(self, *args, **kwargs):
def run(cls, *args, **kwargs): raise self.EXP
raise cls.EXP
job = ErroredBackgroundJob.enqueue(immediate=True) job = ErroredBackgroundJob.enqueue(immediate=True)