PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/laravel/framework/src/Illuminate/Queue/Queue.php

https://gitlab.com/jjpa2018/dashboard
PHP | 398 lines | 196 code | 42 blank | 160 comment | 18 complexity | e3c45a53c7a506b033c322693747e25b MD5 | raw file
  1. <?php
  2. namespace Illuminate\Queue;
  3. use Closure;
  4. use DateTimeInterface;
  5. use Illuminate\Container\Container;
  6. use Illuminate\Contracts\Encryption\Encrypter;
  7. use Illuminate\Contracts\Queue\ShouldBeEncrypted;
  8. use Illuminate\Queue\Events\JobQueued;
  9. use Illuminate\Support\Arr;
  10. use Illuminate\Support\InteractsWithTime;
  11. use Illuminate\Support\Str;
  12. abstract class Queue
  13. {
  14. use InteractsWithTime;
  15. /**
  16. * The IoC container instance.
  17. *
  18. * @var \Illuminate\Container\Container
  19. */
  20. protected $container;
  21. /**
  22. * The connection name for the queue.
  23. *
  24. * @var string
  25. */
  26. protected $connectionName;
  27. /**
  28. * Indicates that jobs should be dispatched after all database transactions have committed.
  29. *
  30. * @return $this
  31. */
  32. protected $dispatchAfterCommit;
  33. /**
  34. * The create payload callbacks.
  35. *
  36. * @var callable[]
  37. */
  38. protected static $createPayloadCallbacks = [];
  39. /**
  40. * Push a new job onto the queue.
  41. *
  42. * @param string $queue
  43. * @param string $job
  44. * @param mixed $data
  45. * @return mixed
  46. */
  47. public function pushOn($queue, $job, $data = '')
  48. {
  49. return $this->push($job, $data, $queue);
  50. }
  51. /**
  52. * Push a new job onto the queue after a delay.
  53. *
  54. * @param string $queue
  55. * @param \DateTimeInterface|\DateInterval|int $delay
  56. * @param string $job
  57. * @param mixed $data
  58. * @return mixed
  59. */
  60. public function laterOn($queue, $delay, $job, $data = '')
  61. {
  62. return $this->later($delay, $job, $data, $queue);
  63. }
  64. /**
  65. * Push an array of jobs onto the queue.
  66. *
  67. * @param array $jobs
  68. * @param mixed $data
  69. * @param string|null $queue
  70. * @return void
  71. */
  72. public function bulk($jobs, $data = '', $queue = null)
  73. {
  74. foreach ((array) $jobs as $job) {
  75. $this->push($job, $data, $queue);
  76. }
  77. }
  78. /**
  79. * Create a payload string from the given job and data.
  80. *
  81. * @param \Closure|string|object $job
  82. * @param string $queue
  83. * @param mixed $data
  84. * @return string
  85. *
  86. * @throws \Illuminate\Queue\InvalidPayloadException
  87. */
  88. protected function createPayload($job, $queue, $data = '')
  89. {
  90. if ($job instanceof Closure) {
  91. $job = CallQueuedClosure::create($job);
  92. }
  93. $payload = json_encode($this->createPayloadArray($job, $queue, $data));
  94. if (JSON_ERROR_NONE !== json_last_error()) {
  95. throw new InvalidPayloadException(
  96. 'Unable to JSON encode payload. Error code: '.json_last_error()
  97. );
  98. }
  99. return $payload;
  100. }
  101. /**
  102. * Create a payload array from the given job and data.
  103. *
  104. * @param string|object $job
  105. * @param string $queue
  106. * @param mixed $data
  107. * @return array
  108. */
  109. protected function createPayloadArray($job, $queue, $data = '')
  110. {
  111. return is_object($job)
  112. ? $this->createObjectPayload($job, $queue)
  113. : $this->createStringPayload($job, $queue, $data);
  114. }
  115. /**
  116. * Create a payload for an object-based queue handler.
  117. *
  118. * @param object $job
  119. * @param string $queue
  120. * @return array
  121. */
  122. protected function createObjectPayload($job, $queue)
  123. {
  124. $payload = $this->withCreatePayloadHooks($queue, [
  125. 'uuid' => (string) Str::uuid(),
  126. 'displayName' => $this->getDisplayName($job),
  127. 'job' => 'Illuminate\Queue\CallQueuedHandler@call',
  128. 'maxTries' => $job->tries ?? null,
  129. 'maxExceptions' => $job->maxExceptions ?? null,
  130. 'failOnTimeout' => $job->failOnTimeout ?? false,
  131. 'backoff' => $this->getJobBackoff($job),
  132. 'timeout' => $job->timeout ?? null,
  133. 'retryUntil' => $this->getJobExpiration($job),
  134. 'data' => [
  135. 'commandName' => $job,
  136. 'command' => $job,
  137. ],
  138. ]);
  139. $command = $this->jobShouldBeEncrypted($job) && $this->container->bound(Encrypter::class)
  140. ? $this->container[Encrypter::class]->encrypt(serialize(clone $job))
  141. : serialize(clone $job);
  142. return array_merge($payload, [
  143. 'data' => array_merge($payload['data'], [
  144. 'commandName' => get_class($job),
  145. 'command' => $command,
  146. ]),
  147. ]);
  148. }
  149. /**
  150. * Get the display name for the given job.
  151. *
  152. * @param object $job
  153. * @return string
  154. */
  155. protected function getDisplayName($job)
  156. {
  157. return method_exists($job, 'displayName')
  158. ? $job->displayName() : get_class($job);
  159. }
  160. /**
  161. * Get the backoff for an object-based queue handler.
  162. *
  163. * @param mixed $job
  164. * @return mixed
  165. */
  166. public function getJobBackoff($job)
  167. {
  168. if (! method_exists($job, 'backoff') && ! isset($job->backoff)) {
  169. return;
  170. }
  171. if (is_null($backoff = $job->backoff ?? $job->backoff())) {
  172. return;
  173. }
  174. return collect(Arr::wrap($backoff))
  175. ->map(function ($backoff) {
  176. return $backoff instanceof DateTimeInterface
  177. ? $this->secondsUntil($backoff) : $backoff;
  178. })->implode(',');
  179. }
  180. /**
  181. * Get the expiration timestamp for an object-based queue handler.
  182. *
  183. * @param mixed $job
  184. * @return mixed
  185. */
  186. public function getJobExpiration($job)
  187. {
  188. if (! method_exists($job, 'retryUntil') && ! isset($job->retryUntil)) {
  189. return;
  190. }
  191. $expiration = $job->retryUntil ?? $job->retryUntil();
  192. return $expiration instanceof DateTimeInterface
  193. ? $expiration->getTimestamp() : $expiration;
  194. }
  195. /**
  196. * Determine if the job should be encrypted.
  197. *
  198. * @param object $job
  199. * @return bool
  200. */
  201. protected function jobShouldBeEncrypted($job)
  202. {
  203. if ($job instanceof ShouldBeEncrypted) {
  204. return true;
  205. }
  206. return isset($job->shouldBeEncrypted) && $job->shouldBeEncrypted;
  207. }
  208. /**
  209. * Create a typical, string based queue payload array.
  210. *
  211. * @param string $job
  212. * @param string $queue
  213. * @param mixed $data
  214. * @return array
  215. */
  216. protected function createStringPayload($job, $queue, $data)
  217. {
  218. return $this->withCreatePayloadHooks($queue, [
  219. 'uuid' => (string) Str::uuid(),
  220. 'displayName' => is_string($job) ? explode('@', $job)[0] : null,
  221. 'job' => $job,
  222. 'maxTries' => null,
  223. 'maxExceptions' => null,
  224. 'failOnTimeout' => false,
  225. 'backoff' => null,
  226. 'timeout' => null,
  227. 'data' => $data,
  228. ]);
  229. }
  230. /**
  231. * Register a callback to be executed when creating job payloads.
  232. *
  233. * @param callable|null $callback
  234. * @return void
  235. */
  236. public static function createPayloadUsing($callback)
  237. {
  238. if (is_null($callback)) {
  239. static::$createPayloadCallbacks = [];
  240. } else {
  241. static::$createPayloadCallbacks[] = $callback;
  242. }
  243. }
  244. /**
  245. * Create the given payload using any registered payload hooks.
  246. *
  247. * @param string $queue
  248. * @param array $payload
  249. * @return array
  250. */
  251. protected function withCreatePayloadHooks($queue, array $payload)
  252. {
  253. if (! empty(static::$createPayloadCallbacks)) {
  254. foreach (static::$createPayloadCallbacks as $callback) {
  255. $payload = array_merge($payload, call_user_func(
  256. $callback, $this->getConnectionName(), $queue, $payload
  257. ));
  258. }
  259. }
  260. return $payload;
  261. }
  262. /**
  263. * Enqueue a job using the given callback.
  264. *
  265. * @param \Closure|string|object $job
  266. * @param string $payload
  267. * @param string $queue
  268. * @param \DateTimeInterface|\DateInterval|int|null $delay
  269. * @param callable $callback
  270. * @return mixed
  271. */
  272. protected function enqueueUsing($job, $payload, $queue, $delay, $callback)
  273. {
  274. if ($this->shouldDispatchAfterCommit($job) &&
  275. $this->container->bound('db.transactions')) {
  276. return $this->container->make('db.transactions')->addCallback(
  277. function () use ($payload, $queue, $delay, $callback, $job) {
  278. return tap($callback($payload, $queue, $delay), function ($jobId) use ($job) {
  279. $this->raiseJobQueuedEvent($jobId, $job);
  280. });
  281. }
  282. );
  283. }
  284. return tap($callback($payload, $queue, $delay), function ($jobId) use ($job) {
  285. $this->raiseJobQueuedEvent($jobId, $job);
  286. });
  287. }
  288. /**
  289. * Determine if the job should be dispatched after all database transactions have committed.
  290. *
  291. * @param \Closure|string|object $job
  292. * @return bool
  293. */
  294. protected function shouldDispatchAfterCommit($job)
  295. {
  296. if (is_object($job) && isset($job->afterCommit)) {
  297. return $job->afterCommit;
  298. }
  299. if (isset($this->dispatchAfterCommit)) {
  300. return $this->dispatchAfterCommit;
  301. }
  302. return false;
  303. }
  304. /**
  305. * Raise the job queued event.
  306. *
  307. * @param string|int|null $jobId
  308. * @param \Closure|string|object $job
  309. * @return void
  310. */
  311. protected function raiseJobQueuedEvent($jobId, $job)
  312. {
  313. if ($this->container->bound('events')) {
  314. $this->container['events']->dispatch(new JobQueued($this->connectionName, $jobId, $job));
  315. }
  316. }
  317. /**
  318. * Get the connection name for the queue.
  319. *
  320. * @return string
  321. */
  322. public function getConnectionName()
  323. {
  324. return $this->connectionName;
  325. }
  326. /**
  327. * Set the connection name for the queue.
  328. *
  329. * @param string $name
  330. * @return $this
  331. */
  332. public function setConnectionName($name)
  333. {
  334. $this->connectionName = $name;
  335. return $this;
  336. }
  337. /**
  338. * Get the container instance being used by the connection.
  339. *
  340. * @return \Illuminate\Container\Container
  341. */
  342. public function getContainer()
  343. {
  344. return $this->container;
  345. }
  346. /**
  347. * Set the IoC container instance.
  348. *
  349. * @param \Illuminate\Container\Container $container
  350. * @return void
  351. */
  352. public function setContainer(Container $container)
  353. {
  354. $this->container = $container;
  355. }
  356. }