diff --git a/src/Lock.php b/src/Lock.php index a5fb112..b681260 100644 --- a/src/Lock.php +++ b/src/Lock.php @@ -30,21 +30,21 @@ public function __construct( * * @param non-empty-string $resource The name of the resource to be locked. * @param non-empty-string|null $id The lock ID. If not specified, a random UUID will be generated. - * @param int|DateInterval $ttl The time-to-live of the lock, in seconds. Defaults to 0 (forever). - * @param int|DateInterval $waitTTL How long to wait to acquire lock until returning false. + * @param int|float|DateInterval $ttl The time-to-live of the lock, in seconds. Defaults to 0 (forever). + * @param int|float|DateInterval $waitTTL How long to wait to acquire lock until returning false. * @return false|non-empty-string Returns lock ID if the lock was acquired successfully, false otherwise. */ public function lock( string $resource, ?string $id = null, - int|DateInterval $ttl = 0, - int|DateInterval $waitTTL = 0, + int|float|DateInterval $ttl = 0, + int|float|DateInterval $waitTTL = 0, ): false|string { $request = new Request(); $request->setResource($resource); $request->setId($id ??= $this->identityGenerator->generate()); - $request->setTtl($this->convertTimeToSeconds($ttl)); - $request->setWait($this->convertTimeToSeconds($waitTTL)); + $request->setTtl($this->convertTimeToMicroseconds($ttl)); + $request->setWait($this->convertTimeToMicroseconds($waitTTL)); $response = $this->call('lock.Lock', $request); @@ -60,21 +60,21 @@ public function lock( * * @param non-empty-string $resource The name of the resource to be locked. * @param non-empty-string|null $id The lock ID. If not specified, a random UUID will be generated. - * @param int|DateInterval $ttl The time-to-live of the lock, in seconds. Defaults to 0 (forever). - * @param int|DateInterval $waitTTL How long to wait to acquire lock until returning false. + * @param int|float|DateInterval $ttl The time-to-live of the lock, in seconds. Defaults to 0 (forever). + * @param int|float|DateInterval $waitTTL How long to wait to acquire lock until returning false. * @return false|non-empty-string Returns lock ID if the lock was acquired successfully, false otherwise. */ public function lockRead( string $resource, ?string $id = null, - int|DateInterval $ttl = 0, - int|DateInterval $waitTTL = 0, + int|float|DateInterval $ttl = 0, + int|float|DateInterval $waitTTL = 0, ): false|string { $request = new Request(); $request->setResource($resource); $request->setId($id ??= $this->identityGenerator->generate()); - $request->setTtl($this->convertTimeToSeconds($ttl)); - $request->setWait($this->convertTimeToSeconds($waitTTL)); + $request->setTtl($this->convertTimeToMicroseconds($ttl)); + $request->setWait($this->convertTimeToMicroseconds($waitTTL)); $response = $this->call('lock.LockRead', $request); @@ -151,28 +151,28 @@ public function exists(string $resource, ?string $id = null): bool * * @param string $resource The name of the resource to update the TTL for. * @param string $id An identifier for the process that is releasing the lock. - * @param int|DateInterval $ttl The new TTL in seconds. + * @param int|float|DateInterval $ttl The new TTL in seconds. * @return bool Returns true on success and false on failure. */ - public function updateTTL(string $resource, string $id, int|DateInterval $ttl): bool + public function updateTTL(string $resource, string $id, int|float|DateInterval $ttl): bool { $request = new Request(); $request->setResource($resource); $request->setId($id); - $request->setTtl($this->convertTimeToSeconds($ttl)); + $request->setTtl($this->convertTimeToMicroseconds($ttl)); $response = $this->call('lock.UpdateTTL', $request); return $response->getOk(); } - private function convertTimeToSeconds(int|DateInterval $ttl): int + private function convertTimeToMicroseconds(int|float|DateInterval $ttl): int { if ($ttl instanceof DateInterval) { - return (int)$ttl->format('%s'); + return (int) round((int)$ttl->format('%s') * 1_000_000); } - return $ttl; + return (int) round($ttl * 1_000_000); } /** @@ -189,4 +189,4 @@ private function call(string $method, Request $request): Response return $response; } -} \ No newline at end of file +} diff --git a/tests/src/LockTest.php b/tests/src/LockTest.php index 2ced210..e7671cc 100644 --- a/tests/src/LockTest.php +++ b/tests/src/LockTest.php @@ -40,9 +40,9 @@ protected function setUp(): void public function testLock( string $method, string $callMethod, - int|\DateInterval|\DateTimeInterface $ttl, - int $expectedTtlSec, - int|\DateInterval|\DateTimeInterface $wait, + int|float|\DateInterval|\DateTimeInterface $ttl, + int $expectedTtlMicroseconds, + int|float|\DateInterval|\DateTimeInterface $wait, int $expectedWaitSec, bool $expectedResult = true, ?string $id = null, @@ -53,7 +53,7 @@ public function testLock( $this->rpc->shouldReceive('call') ->withArgs(function (string $method, Request $request, string $response) use ( - $expectedTtlSec, + $expectedTtlMicroseconds, $expectedWaitSec, $callMethod, $id @@ -61,7 +61,7 @@ public function testLock( return $method === $callMethod && $request->getResource() === 'resource' && $request->getId() === ($id === null ? 'some-id' : $id) - && $request->getTtl() === $expectedTtlSec + && $request->getTtl() === $expectedTtlMicroseconds && $request->getWait() === $expectedWaitSec && $response === Response::class; }) @@ -202,13 +202,15 @@ public static function updateTTLDataProvider(): \Traversable public static function lockDataProvider(): \Generator { - yield 'int' => [10, 10, 8, 8,]; + yield 'int' => [10, 10_000_000, 8, 8_000_000,]; + + yield 'float' => [0.000_01, 10, 0.000_004, 4,]; yield 'date-interval' => [ new \DateInterval('PT10S'), - 10, + 10_000_000, new \DateInterval('PT9S'), - 9, + 9_000_000, ]; }