Skip to content

Commit b5b3082

Browse files
authored
Feature/10215 prevent deadlocks (#153)
Added new section for "Prevent Deadlocks" in "Working With Semaphores"
1 parent 719b4de commit b5b3082

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

content/en/docs/2024.7/Reference/Concepts/working-with/concurrency/semaphores/what-is-a-semaphore.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,27 @@ If a block tries to use a semaphore that already exists (using the same [Scope][
4141

4242
### Preventing Deadlocks
4343

44-
TODO
44+
Deadlocks in flows can occur when multiple executions have acquired different semaphores, and then each execution wants to acquire another semaphore that is being used by another execution, which in turn is waiting for first execution to release its semaphore. E.g.
45+
46+
```
47+
There exists two semaphores:
48+
- Semaphore A with a ConcurrencyLimit of 1 and a queue
49+
- Semaphore B with a ConcurrencyLimit of 1 and a queue
50+
51+
There exists two executions:
52+
- Execution A acquires Semaphore A
53+
- Execution B acquires Semaphore B
54+
- Execution A tries to acquire Semaphore B and joins the queue
55+
- Execution B tries to acquire Semaphore A and joins the queue
56+
57+
Both Execution A and Execution B are deadlocked.
58+
```
59+
60+
In this example, Execution A can't proceed as it's waiting for the semaphore that Execution B is using; which in turn is waiting for the semaphore that Execution A is using.
61+
62+
The best way to avoid these deadlocks is to design your flows to avoid them happening in the first place. In the example above, if both executions will need both semaphores to operate, a change that could be made would be to combine both semaphores into one.
63+
64+
Another way to mitigate the problem would be to use the [QueueTimeout][] property when defining the [QueueSettings][] for each semaphore. Setting the [QueueTimeout][] to a duration reasonably higher than the expected execution time of the operations inside of the semaphore would allow the execution to throw if it has been waiting too long, likely due to a deadlock having occurred. The [SemaphoreCouldNotBeAcquiredException][QueueTimeoutReached] thrown could then be caught to allow the execution to release its semaphores and try again. In the example above, if Semaphore A had a [QueueTimeout][], Execution B timeouts out as it waits to acquire Semaphore A and releases Semaphore B. Execution A then acquires Semaphore B. Execution B retries to acquire Semaphore B and joins the queue. Execution A then finishes its operations, releasing both semaphores and allows Execution B to complete its operations as well.
4565

4666
### Known Limitations
4767

0 commit comments

Comments
 (0)