Coverage for gws-app/gws/base/job/__init__.py: 100%

1 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-05 13:35 +0200

1"""Background jobs. 

2 

3Runs long tasks, such as printing or exporting, outside of the web request 

4that started them. The client starts a job, receives its uid and polls its 

5status until the job is complete, then fetches the result. 

6 

7Submodules 

8---------- 

9 

10- ``manager`` - the job manager (``root.app.jobMgr``). It stores jobs in a 

11 SQLite database, schedules and runs them and handles status and cancel 

12 requests. 

13- ``worker`` - the base class for job workers, with access to the job record 

14 for progress updates and cancellation checks. 

15 

16Jobs 

17---- 

18 

19A job record (``gws.Job``) holds the user, the worker class, the state, 

20progress counters, a payload for the worker and the result. Records live in 

21``jobs.<version>.sqlite`` in the misc directory, so that all server processes 

22see the same jobs. 

23 

24A job goes through the states ``open`` (created), ``running`` and then 

25``complete``, ``error`` or ``cancel``. ``schedule_job`` passes the job to the 

26uWSGI spooler if it is available, otherwise the job runs at once in the 

27current process. ``run_job`` marks the job as running atomically, so a job runs 

28only once, imports the worker class and calls its ``run`` class method. An 

29exception in the worker puts the job into the ``error`` state. 

30 

31Workers 

32------- 

33 

34A worker is a class with a ``run(root, job)`` class method, usually a subclass 

35of ``worker.Object``. While working, it reports progress with ``update_job`` 

36and finally stores the result. ``get_job`` and ``update_job`` raise 

37``gws.JobTerminated`` when the job is no longer running, for example because 

38it was cancelled, which ends the worker. 

39 

40Jobs belong to the user who created them; status, cancel and result requests 

41from other users are answered with ``gws.NotFoundError``. 

42 

43Example:: 

44 

45 class MyWorker(gws.base.job.worker.Object): 

46 @classmethod 

47 def run(cls, root, job): 

48 w = cls(root, job.user, job) 

49 w.work(job.payload) 

50 

51 def work(self, payload): 

52 self.update_job(numSteps=len(payload['items'])) 

53 for n, item in enumerate(payload['items'], 1): 

54 ... 

55 self.update_job(step=n) 

56 self.update_job(state=gws.JobState.complete, result={'count': n}) 

57 

58 mgr = root.app.jobMgr 

59 job = mgr.create_job(MyWorker, user, payload={'items': [...]}) 

60 job = mgr.schedule_job(job) 

61 return mgr.job_status_response(job) 

62""" 

63 

64from . import manager, worker