CallbackEvent.php 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. namespace Illuminate\Console\Scheduling;
  3. use LogicException;
  4. use InvalidArgumentException;
  5. use Illuminate\Contracts\Container\Container;
  6. class CallbackEvent extends Event
  7. {
  8. /**
  9. * The callback to call.
  10. *
  11. * @var string
  12. */
  13. protected $callback;
  14. /**
  15. * The parameters to pass to the method.
  16. *
  17. * @var array
  18. */
  19. protected $parameters;
  20. /**
  21. * Create a new event instance.
  22. *
  23. * @param \Illuminate\Console\Scheduling\EventMutex $mutex
  24. * @param string $callback
  25. * @param array $parameters
  26. * @return void
  27. *
  28. * @throws \InvalidArgumentException
  29. */
  30. public function __construct(EventMutex $mutex, $callback, array $parameters = [])
  31. {
  32. if (! is_string($callback) && ! is_callable($callback)) {
  33. throw new InvalidArgumentException(
  34. 'Invalid scheduled callback event. Must be a string or callable.'
  35. );
  36. }
  37. $this->mutex = $mutex;
  38. $this->callback = $callback;
  39. $this->parameters = $parameters;
  40. }
  41. /**
  42. * Run the given event.
  43. *
  44. * @param \Illuminate\Contracts\Container\Container $container
  45. * @return mixed
  46. *
  47. * @throws \Exception
  48. */
  49. public function run(Container $container)
  50. {
  51. if ($this->description && $this->withoutOverlapping &&
  52. ! $this->mutex->create($this)) {
  53. return;
  54. }
  55. $pid = getmypid();
  56. register_shutdown_function(function () use ($pid) {
  57. if ($pid === getmypid()) {
  58. $this->removeMutex();
  59. }
  60. });
  61. parent::callBeforeCallbacks($container);
  62. try {
  63. $response = $container->call($this->callback, $this->parameters);
  64. } finally {
  65. $this->removeMutex();
  66. parent::callAfterCallbacks($container);
  67. }
  68. return $response;
  69. }
  70. /**
  71. * Clear the mutex for the event.
  72. *
  73. * @return void
  74. */
  75. protected function removeMutex()
  76. {
  77. if ($this->description) {
  78. $this->mutex->forget($this);
  79. }
  80. }
  81. /**
  82. * Do not allow the event to overlap each other.
  83. *
  84. * @param int $expiresAt
  85. * @return $this
  86. *
  87. * @throws \LogicException
  88. */
  89. public function withoutOverlapping($expiresAt = 1440)
  90. {
  91. if (! isset($this->description)) {
  92. throw new LogicException(
  93. "A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'."
  94. );
  95. }
  96. $this->withoutOverlapping = true;
  97. $this->expiresAt = $expiresAt;
  98. return $this->skip(function () {
  99. return $this->mutex->exists($this);
  100. });
  101. }
  102. /**
  103. * Allow the event to only run on one server for each cron expression.
  104. *
  105. * @return $this
  106. *
  107. * @throws \LogicException
  108. */
  109. public function onOneServer()
  110. {
  111. if (! isset($this->description)) {
  112. throw new LogicException(
  113. "A scheduled event name is required to only run on one server. Use the 'name' method before 'onOneServer'."
  114. );
  115. }
  116. $this->onOneServer = true;
  117. return $this;
  118. }
  119. /**
  120. * Get the mutex name for the scheduled command.
  121. *
  122. * @return string
  123. */
  124. public function mutexName()
  125. {
  126. return 'framework/schedule-'.sha1($this->description);
  127. }
  128. /**
  129. * Get the summary of the event for display.
  130. *
  131. * @return string
  132. */
  133. public function getSummaryForDisplay()
  134. {
  135. if (is_string($this->description)) {
  136. return $this->description;
  137. }
  138. return is_string($this->callback) ? $this->callback : 'Closure';
  139. }
  140. }