TraceableMiddleware.php 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Messenger\Middleware;
  11. use Symfony\Component\Messenger\Envelope;
  12. use Symfony\Component\Stopwatch\Stopwatch;
  13. /**
  14. * Collects some data about a middleware.
  15. *
  16. * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
  17. */
  18. class TraceableMiddleware implements MiddlewareInterface
  19. {
  20. private $stopwatch;
  21. private $busName;
  22. private $eventCategory;
  23. public function __construct(Stopwatch $stopwatch, string $busName, string $eventCategory = 'messenger.middleware')
  24. {
  25. $this->stopwatch = $stopwatch;
  26. $this->busName = $busName;
  27. $this->eventCategory = $eventCategory;
  28. }
  29. /**
  30. * {@inheritdoc}
  31. */
  32. public function handle(Envelope $envelope, StackInterface $stack): Envelope
  33. {
  34. $stack = new TraceableStack($stack, $this->stopwatch, $this->busName, $this->eventCategory);
  35. try {
  36. return $stack->next()->handle($envelope, $stack);
  37. } finally {
  38. $stack->stop();
  39. }
  40. }
  41. }
  42. /**
  43. * @internal
  44. */
  45. class TraceableStack implements StackInterface
  46. {
  47. private $stack;
  48. private $stopwatch;
  49. private $busName;
  50. private $eventCategory;
  51. private $currentEvent;
  52. public function __construct(StackInterface $stack, Stopwatch $stopwatch, string $busName, string $eventCategory)
  53. {
  54. $this->stack = $stack;
  55. $this->stopwatch = $stopwatch;
  56. $this->busName = $busName;
  57. $this->eventCategory = $eventCategory;
  58. }
  59. /**
  60. * {@inheritdoc}
  61. */
  62. public function next(): MiddlewareInterface
  63. {
  64. if (null !== $this->currentEvent && $this->stopwatch->isStarted($this->currentEvent)) {
  65. $this->stopwatch->stop($this->currentEvent);
  66. }
  67. if ($this->stack === $nextMiddleware = $this->stack->next()) {
  68. $this->currentEvent = 'Tail';
  69. } else {
  70. $this->currentEvent = sprintf('"%s"', get_debug_type($nextMiddleware));
  71. }
  72. $this->currentEvent .= sprintf(' on "%s"', $this->busName);
  73. $this->stopwatch->start($this->currentEvent, $this->eventCategory);
  74. return $nextMiddleware;
  75. }
  76. public function stop(): void
  77. {
  78. if (null !== $this->currentEvent && $this->stopwatch->isStarted($this->currentEvent)) {
  79. $this->stopwatch->stop($this->currentEvent);
  80. }
  81. $this->currentEvent = null;
  82. }
  83. }