8000 Feedbacks · symfony/symfony@e96f873 · GitHub
[go: up one dir, main page]

Skip to content

Commit e96f873

Browse files
Feedbacks
1 parent cefcd15 commit e96f873

File tree

4 files changed

+61
-15
lines changed

4 files changed

+61
-15
lines changed

src/Symfony/Component/Messenger/Message/LockableMessageInterface.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ interface LockableMessageInterface
1717
* Returns null if you want to force the dispatch of the message.
1818
*/
1919
public function getKey(): ?string;
20+
21+
/**
22+
* Should we release the lock before calling the handler or after.
23+
*/
24+
public function shouldBeReleasedBeforeHandlerCall(): bool;
2025
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Message;
13+
14+
interface TTLAwareLockableMessageInterface extends LockableMessageInterface
15+
{
16+
public function getTTL(): ?int;
17+
}

src/Symfony/Component/Messenger/Middleware/LockMiddleware.php

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Lock\LockFactory;
1515
use Symfony\Component\Messenger\Envelope;
1616
use Symfony\Component\Messenger\Message\LockableMessageInterface;
17+
use Symfony\Component\Messenger\Message\TTLAwareLockableMessageInterface;
1718
use Symfony\Component\Messenger\Stamp\LockStamp;
1819
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
1920

@@ -35,34 +36,50 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
3536

3637
$message = $envelope->getMessage();
3738

38-
// If we're trying to dispatch a lockable message.
39-
if ($message instanceof LockableMessageInterface && null === $envelope->last(ReceivedStamp::class)) {
40-
$key = $message->getKey();
39+
if (null === $envelope->last(ReceivedStamp::class)) {
40+
if ($message instanceof LockableMessageInterface) {
41+
// If we're trying to dispatch a lockable message.
42+
$key = $message->getKey();
4143

42-
if (null !== $key) {
43-
// The acquire call must be done before stamping the message
44-
// in order to have the full state of the key in the stamp.
45-
$canAcquire = $this->lockFactory->createLock($key, autoRelease: false)->acquire();
44+
if (null !== $key) {
45+
// The acquire call must be done before stamping the message
46+
// in order to have the full state of the key in the stamp.
47+
$lock = $message instanceof TTLAwareLockableMessageInterface
48+
? $this->lockFactory->createLock($key, $message->getTTL(), autoRelease: false)
49+
: $this->lockFactory->createLock($key, autoRelease: false);
50+
$canAcquire = $lock->acquire();
4651

47-
$envelope = $envelope->with(new LockStamp($key));
48-
if (!$canAcquire) {
49-
return $envelope;
52+
$envelope = $envelope->with(new LockStamp($key, $message->shouldBeReleasedBeforeHandlerCall()));
53+
if (!$canAcquire) {
54+
return $envelope;
55+
}
5056
}
5157
}
58+
} else {
59+
$this->releaseLock($envelope, true);
5260
}
5361

5462
try {
5563
$envelope = $stack->next()->handle($envelope, $stack);
5664
} finally {
5765
// If we've received a lockable message, we're releasing it.
5866
if (null !== $envelope->last(ReceivedStamp::class)) {
59-
$stamp = $envelope->last(LockStamp::class);
60-
if ($stamp instanceof LockStamp) {
61-
$this->lockFactory->createLockFromKey($stamp->getKey(), autoRelease: false)->release();
62-
}
67+
$this->releaseLock($envelope, false);
6368
}
6469
}
6570

6671
return $envelope;
6772
}
73+
74+
private function releaseLock(Envelope $envelope, bool $beforeHandlerCall): void
75+
{
76+
$stamp = $envelope->last(LockStamp::class);
77+
if ($stamp instanceof LockStamp && $stamp->shouldBeReleasedBeforHandlerCall() === $beforeHandlerCall) {
78+
$message = $envelope->getMessage();
79+
$lock = $message instanceof TTLAwareLockableMessageInterface
80+
? $this->lockFactory->createLockFromKey($stamp->getKey(), $message->getTTL(), autoRelease: false)
81+
: $this->lockFactory->createLockFromKey($stamp->getKey(), autoRelease: false);
82+
$lock->release();
83+
}
84+
}
6885
}

src/Symfony/Component/Messenger/Stamp/LockStamp.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,21 @@
1616
final class LockStamp implements StampInterface
1717
{
1818
private Key $key;
19+
private bool $shouldBeReleasedBeforeHandlerCall;
1920

20-
public function __construct(Key $key)
21+
public function __construct(Key $key, bool $shouldBeReleasedBeforeHandlerCall)
2122
{
2223
$this->key = $key;
24+
$this->shouldBeReleasedBeforeHandlerCall = $shouldBeReleasedBeforeHandlerCall;
2325
}
2426

2527
public function getKey(): Key
2628
{
2729
return $this->key;
2830
}
31+
32+
public function shouldBeReleasedBeforHandlerCall(): bool
33+
{
34+
return $this->shouldBeReleasedBeforeHandlerCall;
35+
}
2936
}

0 commit comments

Comments
 (0)
0