Locking concurrent calls

← Locking concurrent calls

Ashterix

docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api

en/docs/api/json-rpc-bundle/add_rpc_service/lock.md new file +50 āˆ’0

1 + ## Summary
2 +
3 + | | |
4 + | --- | --- |
5 + | **Classname** | `Lock` |
6 + | **Namespace** | `Ufo\RpcObject\RPC` |
7 + | **Target** | method |
8 +
9 + ```php
10 + public function __construct(
11 + public ?string $paramName = null,
12 + public ?int $ttl = null,
13 + )
14 + ```
15 +
16 + # Locking concurrent calls
17 +
18 + Some methods must not run in parallel: paying for a single order, generating a report, syncing with an external system. The `#[RPC\Lock]` attribute prevents a method from starting while a previous call is still running.
19 +
20 + ```php
21 + use Ufo\RpcObject\RPC;
22 +
23 + #[RPC\Lock(paramName: 'orderId', ttl: RPC\Lock::T_10_SECOND)]
24 + public function pay(string $orderId): bool
25 + {
26 + // ...
27 + }
28 + ```
29 +
30 + * `paramName` — a separate lock for each value of the parameter: two `pay` calls with different `orderId` values run concurrently, with the same one they do not. Without `paramName` the whole method is locked, regardless of the arguments.
31 + * `ttl` — the lock lifetime in seconds, so that it does not remain forever if the process crashes. Constants: `T_SECOND`, `T_2_SECOND`, `T_5_SECOND`, `T_10_SECOND`, `T_20_SECOND`, `T_30_SECOND`.
32 +
33 + The lock is acquired before the method runs (the `rpc.pre_execute` event) and released after it, including on error. Acquisition is blocking (`acquire(true)`): a parallel call with the same key waits until the lock is released. If the lock store reports a conflict, the call fails with an error:
34 +
35 + ```json
36 + {
37 + "jsonrpc": "2.0",
38 + "id": 1,
39 + "error": {
40 + "code": -32400,
41 + "message": "Method 'Order.pay' is locked."
42 + }
43 + }
44 + ```
45 +
46 + :::warning subtitle="Known inconsistency"
47 + In the current version, a conflict is not turned into an error: the parallel call waits for the lock to be released. Details and a workaround are in [Open issues](/docs/api/json-rpc-bundle/developers/known_issues/open).
48 + :::
49 +
50 + Locking is implemented with [Symfony Lock](https://symfony.com/doc/current/components/lock.html); it requires the `ext-sysvsem` extension.