lockFactory = $lockFactory; $this->ttl = $ttl; } /** * @param Envelope $envelope * @param StackInterface $stack * * @return Envelope * * @throws Throwable */ public function handle(Envelope $envelope, StackInterface $stack): Envelope { $message = $envelope->getMessage(); if ($envelope->all(ReceivedStamp::class) && $message instanceof LockableMessage) { $lock = $this->lockFactory->createLock($this->objectHash($message), $this->ttl); if (!$lock->acquire()) { return $envelope; } try { return $stack->next()->handle($envelope, $stack); } catch (Throwable $exception) { throw $exception; } finally { $lock->release(); } } return $stack->next()->handle($envelope, $stack); } /** * @param LockableMessage $message * * @return string */ private function objectHash(LockableMessage $message): string { return hash('crc32', serialize($message)); } }