1414use Symfony \Component \Lock \LockFactory ;
1515use Symfony \Component \Messenger \Envelope ;
1616use Symfony \Component \Messenger \Message \LockableMessageInterface ;
17+ use Symfony \Component \Messenger \Message \TTLAwareLockableMessageInterface ;
1718use Symfony \Component \Messenger \Stamp \LockStamp ;
1819use 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}
0 commit comments