Class CurationLockServiceImpl
- All Implemented Interfaces:
CurationLockService
CurationLockService.
Written straight through the session rather than via a curatable update path, and emitting no audit event — see the interface for why both matter.
-
Nested Class Summary
Nested classes/interfaces inherited from interface CurationLockService
CurationLockService.CurationLockedException -
Field Summary
Fields inherited from interface CurationLockService
DEFAULT_TTL_MINUTES -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionacquire(Investigation ee, String lockedBy, boolean steal, int ttlMinutes) Take or refresh the lock.acquire(Investigation ee, String lockedBy, boolean steal, int ttlMinutes, String runId, String agentName) AsCurationLockService.acquire(Investigation, String, boolean, int), recording WHAT is taking the lock as well as who it is for.current(Collection<Long> investigationIds) The current holders of many datasets, keyed by dataset id, in ONE query.current(Investigation ee) The current holder, or empty when the dataset is free.booleanRelease whoever holds it.booleanisHeldBy(Investigation ee, String username) Whetherusernameholds an unexpired lock.refresh(Investigation ee, String heldBy, int ttlMinutes) Extend the caller's existing lease without taking one they do not hold.booleanrelease(Investigation ee, String heldBy) Release the lock ifheldByholds it.
-
Constructor Details
-
CurationLockServiceImpl
-
-
Method Details
-
acquire
@Transactional public CurationLock acquire(Investigation ee, String lockedBy, boolean steal, int ttlMinutes) Description copied from interface:CurationLockServiceTake or refresh the lock.- Specified by:
acquirein interfaceCurationLockService- Parameters:
steal- permit taking a lock another curator currently holds. Always available to callers by design — there is no unlock ceremony to forget, and a steal destroys nothing, since the displaced curator's DRAFT is a separate row.- Returns:
- the granted lock
-
acquire
@Transactional public CurationLock acquire(Investigation ee, String lockedBy, boolean steal, int ttlMinutes, @Nullable String runId, @Nullable String agentName) Description copied from interface:CurationLockServiceAsCurationLockService.acquire(Investigation, String, boolean, int), recording WHAT is taking the lock as well as who it is for.runId/agentNameare null for a person, which is how a reader tells a curator from a job. SeeCurationLock.getRunId()for why this is stored rather than derived.- Specified by:
acquirein interfaceCurationLockService
-
refresh
@Transactional public Optional<CurationLock> refresh(Investigation ee, String heldBy, int ttlMinutes) Description copied from interface:CurationLockServiceExtend the caller's existing lease without taking one they do not hold. Called on every draft autosave, so working holds the lock and walking away releases it.- Specified by:
refreshin interfaceCurationLockService- Returns:
- the refreshed lock, or empty if
heldBydoes not hold it — a refresh must never quietly become an acquire, or an autosave would steal a lock the curator never asked for
-
release
Description copied from interface:CurationLockServiceRelease the lock ifheldByholds it.- Specified by:
releasein interfaceCurationLockService- Returns:
- whether a lock was released
-
forceRelease
Description copied from interface:CurationLockServiceRelease whoever holds it. For administrators.- Specified by:
forceReleasein interfaceCurationLockService
-
current
Description copied from interface:CurationLockServiceThe current holder, or empty when the dataset is free.An expired row reads as empty rather than as a holder: nothing sweeps expiry, so "is it locked" has to mean "is there an unexpired claim".
- Specified by:
currentin interfaceCurationLockService
-
isHeldBy
Description copied from interface:CurationLockServiceWhetherusernameholds an unexpired lock. This is what sign-off checks.- Specified by:
isHeldByin interfaceCurationLockService
-
current
@Nullable @Transactional(readOnly=true) public Map<Long, CurationLock> current(Collection<Long> investigationIds) Description copied from interface:CurationLockServiceThe current holders of many datasets, keyed by dataset id, in ONE query.Exists because the question is asked about a LIST: the curation queue pages up to 1000 rows, and asking per row is 1000 round-trips to paint one screen. A dataset nobody holds is simply absent from the map rather than mapped to null.
Same expiry rule as
CurationLockService.current(Investigation)— a lapsed claim is not a holder — so a caller can treat presence in this map as "held right now" without re-checking dates.- Specified by:
currentin interfaceCurationLockService
-