In some cases, we want to not schedule a work if it is already scheduled or running.
Typically when asking for the same lazy rendition computation twice in a row on an unchanged document, the first call should schedule a rendition work, the second one shouldn't.
The current code in AbstractLazyCachableRenditionProvider tries to avoid this by doing:
See https://github.com/nuxeo/nuxeo/commit/e67cf15d06257a90df1bd78aaaa2ed5761cae9db and
NXP-20716 for details.
Yet, there are at least 2 issues:
1/ We cannot rely on the work state
Introspect works to deduce a state or a result isn't good:
- There can be some race conditions.
- It's not a work's function to keep a state or a result.
- This is not supported on Stream WorkManager
So we shouldn't be using WorkManager#find(String workId, State state)
that relies on WorkQueuing#find(String workId, State state), thus on:
- Work#getWorkInstanceState() in memory
- RedisWorkQueuing#isWorkInState(String workId, State state) with Redis
2/ The current WorkManager API bypasses the scheduling parameter
Indeed, in WorkManagerImpl#schedule(Work work, Scheduling scheduling, boolean afterCommit), the work is scheduled in any case when using IF_NOT_SCHEDULED or IF_NOT_RUNNING_OR_SCHEDULED:
Use the Key/Value store to save the scheduled and running jobs with a temporary value, "processing" for instance, and let the job remove the key when it's completed.
We should use a short TTL.
Let's try to write a standard pattern for the lazy renditions so that it serves as a global example.