Fix detection of stuck cronjobs
Consider the following scenario:
A cronjob is scheduled to run `0 * * * *` (i.e. every hour). The cronjob
successfully executes it's 23:00 execution belated on 23:30. Then the
nextExec will be 00:00. afterNextExec will be 01:00.
During night time nothing happens within the community, until at 05:xx when
the first user wakes up and opens their web browser. It restores two tabs
with our community and fetches them. Now the following will happen:
1. Request 1: Notices that the cronjob is due (00:00 < 05:xx). Setting
the cronjob's state to pending and starting execution.
2. Request 2: Notices that the cronjob is overdue (01:00 < 05:xx,
state = pending). Logging an error about a stuck job and
setting the cronjob's state to ready.
3. Request 1: Finishes executing the cronjob and updates nextExec = 06:00,
afterNextExec = 07:00, also setting the cronjob's state to
ready.
Fix this issue by updating the times for the next executions together with
the update of the state in a single database query / transaction. This will
prevent other requests from seeing the cronjob with state = pending or
state = executing and an way outdated date.
A side effect of this change is that cronjobs will match the intended
schedule better.
Consider the following:
A cronjob running every minute, taking 5 seconds to execute. The execution
is triggered at 00:00:58. It will finish executing 00:01:03. Previously the
nextExec would be set to 00:02:00, now it will be 00:01:00. Thus the first
request after 00:01:03 (i.e. once the state is set back to ready) will
trigger execution, more closely matching the intended schedule.