-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClosure_Job.php
More file actions
121 lines (102 loc) · 2.65 KB
/
Copy pathClosure_Job.php
File metadata and controls
121 lines (102 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
/**
* Closure_Job class file
*
* phpcs:disable Squiz.Commenting.VariableComment.Missing
*
* @package Mantle
*/
namespace Mantle\Queue;
use Closure;
use DateTimeInterface;
use Laravel\SerializableClosure\SerializableClosure;
use Mantle\Contracts\Queue\Can_Queue;
use ReflectionFunction;
use Throwable;
/**
* Closure Job
*
* Storage of the closure-based queue job.
*/
class Closure_Job implements Can_Queue {
/**
* The delay before the job will be run.
*/
public int|DateTimeInterface $delay;
/**
* The callbacks that should be run on failure.
*
* @var array<Closure|SerializableClosure>
*/
public array $failure_callbacks = [];
/**
* Create a new job instance.
*
* @param Closure $closure Closure to wrap.
*/
public static function create( Closure $closure ): Closure_Job {
$reflection_closure = new \ReflectionFunction( $closure );
// Check if the closure is bound to WP_CLI\Runner. If so, unbind it because
// this will cause a serialization error. Without this, we cannot dispatch
// to the queue from WP-CLI.
if ( \WP_CLI\Runner::class === $reflection_closure->getClosureScopeClass()?->getName() ) {
$closure = $closure->bindTo( null, null );
}
return new self( new SerializableClosure( $closure ) );
}
/**
* Constructor.
*
* @param SerializableClosure $closure Serialized closure to wrap.
*/
public function __construct( public SerializableClosure $closure ) {
}
/**
* Handle the queue job.
*/
public function handle(): void {
$callback = $this->closure->getClosure();
$callback();
}
/**
* Set the delay before the job will be run.
*
* @param DateTimeInterface|int $delay Delay in seconds or DateTime instance.
*/
public function delay( DateTimeInterface|int $delay ): static {
$this->delay = $delay;
return $this;
}
/**
* Add a callback to be executed if the job fails.
*
* @param mixed $callback
*/
public function on_failure( $callback ): static {
$this->failure_callbacks[] = $callback instanceof Closure
? new SerializableClosure( $callback )
: $callback;
return $this;
}
/**
* Handle a job failure.
*
* @param \Throwable $e Exception.
*/
public function failed( Throwable $e ): void {
foreach ( $this->failure_callbacks as $failure_callback ) {
$failure_callback( $e );
}
}
/**
* Get the queue job ID.
*/
public function get_id(): string {
$closure = $this->closure->getClosure();
if ( ! $closure ) { // @phpstan-ignore-line negated
return 'Invalid Closure Job';
}
$reflection = new ReflectionFunction( $closure );
return 'Closure (' . basename( (string) $reflection->getFileName() ) . ':' . $reflection->getStartLine() . ')';
}
}