What mechanism is in place to prevent completion while another task is attempting to complete? Race event?

Given a user task (TaskA) and User1 submits for completion, while TaskA is attempting to complete what mechanism stops User2 from attempting a completion of TaskA and executing the associate listeners, subsequent async tasks, etc ?

Hi Stephen,

I would have thought that a user task should be claimed by a user prior to completion and thus the race condition is at the claim stage…

regards

Rob

Rob in that example: other than the UI, what would stop User1 from triggering a submission twice?

Hi Stephen,

I dont think you can eliminate a race condition on submission (there are lots of techniques to minimise duplicate submissions, the UI, de-bounce on button etc), but ultimately because its an API call, you cant eliminate duplicate requests…

Lets suppose the user task is in one of three states; (1) Claimed and pending a completion command, (2) Completed or (3) Completing (received a completion command but still processing)

Case 2 should be benign and second completion command in this case should just throw an error.
Case 1 is an enabler of a potential race condition, so we dont need to consider if further.
Case 3 is the interesting one where the race condition manifests itself. The ‘first’ completion command will run to the next wait state. The second completion command will also run to the next wait state, however I would expect an optimistic locking exception to be thrown. As the first completion command’s effects wil have been flushed to the database, a subsequent 3rd completion command will likely follow case 2 above…

So the interesting part is now how idempotent are the user task completion semantics? The intrinsic task completion API is not completely (transparently) idempotent, however the engine will maintain a consistent state. However, if you add listeners with additional side-effects, or perform many services tasks etc before the next wait state, its a case of the more you do, the less consistent you may leave the solution state in…

So in thinking about this, to be safe, guiding principles could be;
Always set a User Task to async after.
Ensure business object state changes made within a user task are idempotent state changes

regards

Rob