Timebox.php 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. namespace Illuminate\Support;
  3. use Throwable;
  4. class Timebox
  5. {
  6. /**
  7. * Indicates if the timebox is allowed to return early.
  8. *
  9. * @var bool
  10. */
  11. public $earlyReturn = false;
  12. /**
  13. * Invoke the given callback within the specified timebox minimum.
  14. *
  15. * @template TCallReturnType
  16. *
  17. * @param (callable($this): TCallReturnType) $callback
  18. * @param int $microseconds
  19. * @return TCallReturnType
  20. */
  21. public function call(callable $callback, int $microseconds)
  22. {
  23. $exception = null;
  24. $start = microtime(true);
  25. try {
  26. $result = $callback($this);
  27. } catch (Throwable $caught) {
  28. $exception = $caught;
  29. }
  30. $remainder = intval($microseconds - ((microtime(true) - $start) * 1000000));
  31. if (! $this->earlyReturn && $remainder > 0) {
  32. $this->usleep($remainder);
  33. }
  34. if ($exception) {
  35. throw $exception;
  36. }
  37. return $result;
  38. }
  39. /**
  40. * Indicate that the timebox can return early.
  41. *
  42. * @return $this
  43. */
  44. public function returnEarly()
  45. {
  46. $this->earlyReturn = true;
  47. return $this;
  48. }
  49. /**
  50. * Indicate that the timebox cannot return early.
  51. *
  52. * @return $this
  53. */
  54. public function dontReturnEarly()
  55. {
  56. $this->earlyReturn = false;
  57. return $this;
  58. }
  59. /**
  60. * Sleep for the specified number of microseconds.
  61. *
  62. * @param int $microseconds
  63. * @return void
  64. */
  65. protected function usleep(int $microseconds)
  66. {
  67. Sleep::usleep($microseconds);
  68. }
  69. }