Exception
11 months ago
BinaryValue.php
11 months ago
DynamoDbClient.php
11 months ago
LockingSessionConnection.php
11 months ago
Marshaler.php
11 months ago
NumberValue.php
11 months ago
SessionConnectionConfigTrait.php
11 months ago
SessionConnectionInterface.php
11 months ago
SessionHandler.php
11 months ago
SetValue.php
11 months ago
StandardSessionConnection.php
11 months ago
WriteRequestBatch.php
11 months ago
LockingSessionConnection.php
59 lines
| 1 | <?php |
| 2 | namespace Aws\DynamoDb; |
| 3 | |
| 4 | use Aws\DynamoDb\Exception\DynamoDbException; |
| 5 | |
| 6 | /** |
| 7 | * The locking connection adds locking logic to the read operation. |
| 8 | */ |
| 9 | class LockingSessionConnection extends StandardSessionConnection |
| 10 | { |
| 11 | public function __construct(DynamoDbClient $client, array $config = []) |
| 12 | { |
| 13 | parent::__construct($client, $config); |
| 14 | } |
| 15 | |
| 16 | /** |
| 17 | * {@inheritdoc} |
| 18 | * Retries the request until the lock can be acquired |
| 19 | */ |
| 20 | public function read($id) |
| 21 | { |
| 22 | // Create the params for the UpdateItem operation so that a lock can be |
| 23 | // set and item returned (via ReturnValues) in a one, atomic operation. |
| 24 | $params = [ |
| 25 | 'TableName' => $this->getTableName(), |
| 26 | 'Key' => $this->formatKey($id), |
| 27 | 'Expected' => ['lock' => ['Exists' => false]], |
| 28 | 'AttributeUpdates' => ['lock' => ['Value' => ['N' => '1']]], |
| 29 | 'ReturnValues' => 'ALL_NEW', |
| 30 | ]; |
| 31 | |
| 32 | // Acquire the lock and fetch the item data. |
| 33 | $timeout = time() + $this->getMaxLockWaitTime(); |
| 34 | while (true) { |
| 35 | try { |
| 36 | $item = []; |
| 37 | $result = $this->client->updateItem($params); |
| 38 | if (isset($result['Attributes'])) { |
| 39 | foreach ($result['Attributes'] as $key => $value) { |
| 40 | $item[$key] = current($value); |
| 41 | } |
| 42 | } |
| 43 | return $item; |
| 44 | } catch (DynamoDbException $e) { |
| 45 | if ($e->getAwsErrorCode() === 'ConditionalCheckFailedException' |
| 46 | && time() < $timeout |
| 47 | ) { |
| 48 | usleep(rand( |
| 49 | $this->getMinLockRetryMicrotime(), |
| 50 | $this->getMaxLockRetryMicrotime() |
| 51 | )); |
| 52 | } else { |
| 53 | break; |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | } |
| 58 | } |
| 59 |