14
14
use Symfony \Component \Lock \LockFactory ;
15
15
use Symfony \Component \Messenger \Envelope ;
16
16
use Symfony \Component \Messenger \Message \LockableMessageInterface ;
17
+ use Symfony \Component \Messenger \Message \TTLAwareLockableMessageInterface ;
17
18
use Symfony \Component \Messenger \Stamp \LockStamp ;
18
19
use Symfony \Component \Messenger \Stamp \ReceivedStamp ;
19
20
@@ -35,34 +36,50 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
35
36
36
37
$ message = $ envelope ->getMessage ();
37
38
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 ();
41
43
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 ();
46
51
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
+ }
50
56
}
51
57
}
58
+ } else {
59
+ $ this ->releaseLock ($ envelope , true );
52
60
}
53
61
54
62
try {
55
63
$ envelope = $ stack ->next ()->handle ($ envelope , $ stack );
56
64
} finally {
57
65
// If we've received a lockable message, we're releasing it.
58
66
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 );
63
68
}
64
69
}
65
70
66
71
return $ envelope ;
67
72
}
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
+ }
68
85
}
0 commit comments