Per review feedback: note in the lockTask docblock that the guard changed from
`status != RUNNING` to `status = SCHEDULED`, and that callers must now treat a
0 return as "the task is no longer claimable" rather than assuming success.
Signed-off-by: Yoan Bozhilov <bygadd@gmail.com>
Assisted-by: Claude Code:claude-opus-4-8
Address review feedback (@marcelklehr, Copilot):
- lockTask claims only SCHEDULED tasks (was status != RUNNING) and stamps
started_at in the same atomic UPDATE, so a finished task cannot be re-claimed
and the external-provider claim path records started_at as well.
- claimWithBoundedRetry re-reads after lockTask instead of a follow-up UPDATE.
- Oracle joins SQLite on the bounded-retry fallback: Oracle cannot combine a
row-limiting clause with FOR UPDATE (ORA-02014), which failed the claim tests
on Oracle CI.
- Reword the worker docblock/comments to "prefer oldest available" (parallel
SKIP LOCKED does not guarantee a strict global order).
- Add a regression test that lockTask does not resurrect a finished task.
Signed-off-by: Yoan Bozhilov <bygadd@gmail.com>
Assisted-by: Claude Code:claude-opus-4-8
Replace the worker retry/ignore-list claim-loop with a single atomic
SELECT ... FOR UPDATE SKIP LOCKED claim (SQLite bounded-retry fallback),
preserving the no-duplicate guarantee while removing the thundering-herd
contention that throttled backlog draining. Add a (status,type,last_updated)
index via the table-creating migration + db:add-missing-indices listener.
Signed-off-by: Yoan Bozhilov <bygadd@gmail.com>
Assisted-by: Claude Code:claude-opus-4-8
The availableTaskTypes cache stores serialized arrays containing
ShapeDescriptor objects, ShapeEnumValue objects, and EShapeType enum
values. The unserialize() call did not restrict which classes could
be instantiated.
Restrict deserialization to the three known types:
- OCP\TaskProcessing\ShapeDescriptor
- OCP\TaskProcessing\ShapeEnumValue
- OCP\TaskProcessing\EShapeType
This prevents PHP Object Injection if an attacker gains write access
to the distributed cache backend.
Signed-off-by: El Mehdi Abenhazou <mehdiananas007@gmail.com>
The availableTaskTypes cache stores serialized arrays containing
ShapeDescriptor objects, ShapeEnumValue objects, and EShapeType enum
values. The unserialize() call did not restrict which classes could
be instantiated.
Restrict deserialization to the three known types:
- OCP\TaskProcessing\ShapeDescriptor
- OCP\TaskProcessing\ShapeEnumValue
- OCP\TaskProcessing\EShapeType
This prevents PHP Object Injection if an attacker gains write access
to the distributed cache backend (e.g., a Redis instance without
authentication or with weak ACLs), which is a known real-world attack
vector in shared hosting and container environments.
The diff can be checked using: git diff --ignore-all-space --ignore-blank-lines
To see only the changes not related to blank lines.
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>