22
33namespace Stackkit \LaravelGoogleCloudTasksQueue ;
44
5+ use Google \Cloud \Tasks \V2 \Attempt ;
56use Google \Cloud \Tasks \V2 \CloudTasksClient ;
7+ use Google \Cloud \Tasks \V2 \RetryConfig ;
68use Illuminate \Http \Request ;
79use Illuminate \Queue \Events \JobFailed ;
810use Illuminate \Queue \Worker ;
@@ -14,6 +16,16 @@ class TaskHandler
1416 private $ publicKey ;
1517 private $ config ;
1618
19+ /**
20+ * @var CloudTasksQueue
21+ */
22+ private $ queue ;
23+
24+ /**
25+ * @var RetryConfig
26+ */
27+ private $ retryConfig = null ;
28+
1729 public function __construct (CloudTasksClient $ client , Request $ request , OpenIdVerificator $ publicKey )
1830 {
1931 $ this ->client = $ client ;
@@ -31,6 +43,8 @@ public function handle($task = null)
3143
3244 $ this ->loadQueueConnectionConfiguration ($ task );
3345
46+ $ this ->setQueue ();
47+
3448 $ this ->authorizeRequest ();
3549
3650 $ this ->listenForEvents ();
@@ -48,6 +62,11 @@ private function loadQueueConnectionConfiguration($task)
4862 );
4963 }
5064
65+ private function setQueue ()
66+ {
67+ $ this ->queue = new CloudTasksQueue ($ this ->config , $ this ->client );
68+ }
69+
5170 /**
5271 * @throws CloudTasksException
5372 */
@@ -122,29 +141,63 @@ private function listenForEvents()
122141 */
123142 private function handleTask ($ task )
124143 {
125- $ job = new CloudTasksJob ($ task );
144+ $ job = new CloudTasksJob ($ task , $ this ->queue );
145+
146+ $ this ->loadQueueRetryConfig ();
126147
127148 $ job ->setAttempts (request ()->header ('X-CloudTasks-TaskRetryCount ' ) + 1 );
128149 $ job ->setQueue (request ()->header ('X-Cloudtasks-Queuename ' ));
129- $ job ->setMaxTries ($ this ->getQueueMaxTries ($ job ));
150+ $ job ->setMaxTries ($ this ->retryConfig ->getMaxAttempts ());
151+
152+ // If the job is being attempted again we also check if a
153+ // max retry duration has been set. If that duration
154+ // has passed, it should stop trying altogether.
155+ if ($ job ->attempts () > 1 ) {
156+ $ job ->setRetryUntil ($ this ->getRetryUntilTimestamp ($ job ));
157+ }
130158
131159 $ worker = $ this ->getQueueWorker ();
132160
133161 $ worker ->process ($ this ->config ['connection ' ], $ job , new WorkerOptions ());
134162 }
135163
136- private function getQueueMaxTries ( CloudTasksJob $ job )
164+ private function loadQueueRetryConfig ( )
137165 {
138166 $ queueName = $ this ->client ->queueName (
139167 $ this ->config ['project ' ],
140168 $ this ->config ['location ' ],
141- $ job -> getQueue ( )
169+ request ()-> header ( ' X-Cloudtasks-Queuename ' )
142170 );
143171
144- return $ this ->client
145- ->getQueue ($ queueName )
146- ->getRetryConfig ()
147- ->getMaxAttempts ();
172+ $ this ->retryConfig = $ this ->client ->getQueue ($ queueName )->getRetryConfig ();
173+ }
174+
175+ private function getRetryUntilTimestamp (CloudTasksJob $ job )
176+ {
177+ $ task = $ this ->client ->getTask (
178+ $ this ->client ->taskName (
179+ $ this ->config ['project ' ],
180+ $ this ->config ['location ' ],
181+ $ job ->getQueue (),
182+ request ()->header ('X-Cloudtasks-Taskname ' )
183+ )
184+ );
185+
186+ $ attempt = $ task ->getFirstAttempt ();
187+
188+ if (!$ attempt instanceof Attempt) {
189+ return null ;
190+ }
191+
192+ if (! $ this ->retryConfig ->hasMaxRetryDuration ()) {
193+ return null ;
194+ }
195+
196+ $ maxDurationInSeconds = $ this ->retryConfig ->getMaxRetryDuration ()->getSeconds ();
197+
198+ $ firstAttemptTimestamp = $ attempt ->getDispatchTime ()->toDateTime ()->getTimestamp ();
199+
200+ return $ firstAttemptTimestamp + $ maxDurationInSeconds ;
148201 }
149202
150203 /**
0 commit comments