Skip to content

Commit 5888beb

Browse files
hunterinoclaude
andcommitted
Reduce default job lock expiration from 24h to 2h (#17)
The job scheduler uses expireLockTime to detect and recover from stale locks caused by server crashes during job execution. Previous behavior: Default of 1440 minutes (24 hours) meant jobs could be blocked for an entire day if a server crashed mid-execution. New behavior: Default reduced to 120 minutes (2 hours), which: - Allows recovery from stale locks much faster - Still provides enough time for most long-running jobs - Jobs that need more time can set expireLockTime explicitly Updated ServiceJob entity documentation to reflect new default. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 87872d9 commit 5888beb

2 files changed

Lines changed: 6 additions & 3 deletions

File tree

framework/entity/ServiceEntities.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ along with this software (see the LICENSE.md file). If not, see
5858
<field name="expireLockTime" type="number-integer"><description>Ignore lock and run anyway after this many
5959
minutes. This should generally be much greater than the longest time the service is expected to run. This is
6060
the mechanism for recovering jobs after a run failed in a way that did not clean up the ServiceJobRunLock
61-
record. Defaults to 24 hours (1440 minutes) to make sure jobs get recovered.</description></field>
61+
record. Defaults to 2 hours (120 minutes) to balance recovery speed with allowing long-running jobs.
62+
For very long-running jobs, increase this value appropriately.</description></field>
6263
<field name="minRetryTime" type="number-integer">
6364
<description>Minimum time between retries after an error (based on most recent ServiceJobRun record), in minutes</description></field>
6465
<field name="priority" type="number-integer">

framework/src/main/groovy/org/moqui/impl/service/ScheduledJobRunner.groovy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,11 @@ class ScheduledJobRunner implements Runnable {
153153
ZonedDateTime lastRunDt = (lastRunTime != (Timestamp) null) ?
154154
ZonedDateTime.ofInstant(Instant.ofEpochMilli(lastRunTime.getTime()), now.getZone()) : null
155155
if (serviceJobRunLock != null && serviceJobRunLock.jobRunId != null && lastRunDt != null) {
156-
// for failure with no lock reset: run recovery, based on expireLockTime (default to 1440 minutes)
156+
// for failure with no lock reset: run recovery, based on expireLockTime
157+
// Issue #591/#17: Reduced default from 1440 (24 hours) to 120 minutes (2 hours)
158+
// This prevents jobs being blocked for too long if a server crashes mid-execution
157159
Long expireLockTime = (Long) serviceJob.expireLockTime
158-
if (expireLockTime == null) expireLockTime = 1440L
160+
if (expireLockTime == null) expireLockTime = 120L
159161
ZonedDateTime lockCheckTime = now.minusMinutes(expireLockTime.intValue())
160162
if (lastRunDt.isBefore(lockCheckTime)) {
161163
// recover failed job without lock reset, run it if schedule says to

0 commit comments

Comments
 (0)