-
Notifications
You must be signed in to change notification settings - Fork 0
/
Retry.php
158 lines (133 loc) · 3.25 KB
/
Retry.php
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php
/**
* Class Retry
*
* Helper to call a given callable multiple times if the first time it fails.
* Allows you to define what a fail means, how many retries, and how much time between retries.
*
* Note that this is not async. The execution will be stopped here until all retries finish
* or the execution is succesful.
*
*/
class Retry {
/**
* How many times are we going to try?
* Default is 1.
* @var int
*/
protected $times = 1;
/**
* How many seconds between retries.
* Default is 1.
* @var int
*/
protected $delay = 1;
/**
* Function that we're going to execute.
* @var callable
*/
protected $fn = null;
/**
*
* @var array
*/
protected $args = array();
/**
* Callback to define if the execution was failed or not.
* @var callable
*/
protected $failed_if = 'is_wp_error';
/**
* Gives a Retry object. Needs to be initialized with a callable.
* That callable is the function we're going to try to execute
* and retry if it fails.
*
* @param callable $fn
*/
public function __construct( callable $fn ) {
$this->fn = $fn;
}
/**
* Optional array of arguments to pass to the function
* we're going to try to execute.
*
* @param array $args
*
* @return $this
*/
public function with_args( $args ) {
$this->args = $args;
return $this;
}
/**
* How many times are we going to retry?
* Default is 1.
*
* @param $times
*
* @return $this
*/
public function times( $times ) {
$this->times = $times;
return $this;
}
/**
* How many seconds do we wait between retries?
* Default is 1.
*
* @param $seconds
*
* @return $this
*/
public function with_delay( $seconds ) {
$this->delay = $seconds;
return $this;
}
/**
* How do we know if the execution failed?
*
* @param callable $fn Should recieve a single parameter $response and should
* return a bool. True means the call was failed, false means
* that it was succesful and we're good to go.
*
*
* Default is is_wp_error
*
* @return $this
*/
public function failed_if( callable $fn ) {
$this->failed_if = $fn;
return $this;
}
/**
* Start the execution!
*
* @return mixed
*/
public function go() {
if ( empty( $this->failed_if ) ) {
$this->failed_if( 'is_wp_error' );
}
$result = null;
for ( $i = 0; $i < $this->times; $i ++ ) {
$result = call_user_func_array( $this->fn, $this->args );
$failed = call_user_func_array( $this->failed_if, array( $result ) );
if ( ! $failed ) {
return $result;
}
sleep( $this->delay );
}
return $result;
}
/**
* Just a wrapper around the instance creation.
* Pure syntax sugar.
*
* @param callable $fn
*
* @return \MacMillan\Retry
*/
public static function calling( callable $fn ) {
return new self( $fn );
}
}