55namespace Stackkit \LaravelGoogleCloudTasksQueue ;
66
77use Closure ;
8+ use Exception ;
89use Illuminate \Support \Str ;
910
1011use function Safe \json_decode ;
2324use Illuminate \Contracts \Queue \Queue as QueueContract ;
2425use Stackkit \LaravelGoogleCloudTasksQueue \Events \TaskCreated ;
2526
27+ /**
28+ * @phpstan-import-type QueueConfig from CloudTasksConnector
29+ * @phpstan-import-type JobShape from CloudTasksJob
30+ * @phpstan-import-type JobBeforeDispatch from CloudTasksJob
31+ *
32+ * @phpstan-type JobOptions array{
33+ * job?: Closure|string|object,
34+ * delay?: ?int
35+ * }
36+ */
2637class CloudTasksQueue extends LaravelQueue implements QueueContract
2738{
28- private static ?Closure $ handlerUrlCallback = null ;
39+ protected static ?Closure $ handlerUrlCallback = null ;
2940
30- private static ?Closure $ taskHeadersCallback = null ;
41+ protected static ?Closure $ taskHeadersCallback = null ;
3142
3243 /** @var (Closure(IncomingTask): WorkerOptions)|null */
33- private static ?Closure $ workerOptionsCallback = null ;
44+ protected static ?Closure $ workerOptionsCallback = null ;
3445
35- public function __construct (public array $ config , public CloudTasksClient $ client , public $ dispatchAfterCommit = false )
36- {
46+ /**
47+ * @param QueueConfig $config
48+ */
49+ public function __construct (
50+ public array $ config ,
51+ public CloudTasksClient $ client ,
52+ // @phpstan-ignore-next-line
53+ public $ dispatchAfterCommit = false ,
54+ ) {
3755 //
3856 }
3957
@@ -92,15 +110,20 @@ public function size($queue = null): int
92110 /**
93111 * Push a new job onto the queue.
94112 *
95- * @param string|object $job
113+ * @param string|Closure|JobBeforeDispatch $job
96114 * @param mixed $data
97115 * @param string|null $queue
98- * @return void
116+ * @return mixed
99117 */
100118 public function push ($ job , $ data = '' , $ queue = null )
101119 {
102- if (! ($ job instanceof Closure)) {
103- $ job ->queue = $ queue ?? $ job ->queue ?? $ this ->config ['queue ' ];
120+ if (! $ queue ) {
121+ $ queue = $ this ->getQueueForJob ($ job );
122+ }
123+
124+ if (is_object ($ job ) && ! $ job instanceof Closure) {
125+ /** @var JobBeforeDispatch $job */
126+ $ job ->queue = $ queue ;
104127 }
105128
106129 return $ this ->enqueueUsing (
@@ -119,6 +142,7 @@ function ($payload, $queue) use ($job) {
119142 *
120143 * @param string $payload
121144 * @param string|null $queue
145+ * @param JobOptions $options
122146 * @return string
123147 */
124148 public function pushRaw ($ payload , $ queue = null , array $ options = [])
@@ -133,13 +157,18 @@ public function pushRaw($payload, $queue = null, array $options = [])
133157 * Push a new job onto the queue after a delay.
134158 *
135159 * @param \DateTimeInterface|\DateInterval|int $delay
136- * @param string|object $job
160+ * @param Closure| string|JobBeforeDispatch $job
137161 * @param mixed $data
138162 * @param string|null $queue
139- * @return void
163+ * @return mixed
140164 */
141165 public function later ($ delay , $ job , $ data = '' , $ queue = null )
142166 {
167+ // Laravel pls fix your typehints
168+ if (! $ queue ) {
169+ $ queue = $ this ->getQueueForJob ($ job );
170+ }
171+
143172 return $ this ->enqueueUsing (
144173 $ job ,
145174 $ this ->createPayload ($ job , $ queue , $ data ),
@@ -157,7 +186,7 @@ function ($payload, $queue, $delay) use ($job) {
157186 * @param string|null $queue
158187 * @param string $payload
159188 * @param \DateTimeInterface|\DateInterval|int $delay
160- * @param string|object $job
189+ * @param Closure| string|object|null $job
161190 * @return string
162191 */
163192 protected function pushToCloudTasks ($ queue , $ payload , $ delay , mixed $ job )
@@ -166,6 +195,7 @@ protected function pushToCloudTasks($queue, $payload, $delay, mixed $job)
166195
167196 $ payload = (array ) json_decode ($ payload , true );
168197
198+ /** @var JobShape $payload */
169199 $ task = tap (new Task )->setName ($ this ->taskName ($ queue , $ payload ['displayName ' ]));
170200
171201 $ payload = $ this ->enrichPayloadWithAttempts ($ payload );
@@ -200,33 +230,43 @@ private function taskName(string $queueName, string $displayName): string
200230 );
201231 }
202232
203- private function enrichPayloadWithAttempts (
204- array $ payload ,
205- ): array {
233+ /**
234+ * @param JobShape $payload
235+ * @return JobShape
236+ */
237+ private function enrichPayloadWithAttempts (array $ payload ): array
238+ {
206239 $ payload ['internal ' ] = [
207240 'attempts ' => $ payload ['internal ' ]['attempts ' ] ?? 0 ,
208241 ];
209242
210243 return $ payload ;
211244 }
212245
213- /** @param string|object $job */
214- public function addPayloadToTask (array $ payload , Task $ task , mixed $ job ): Task
246+ /**
247+ * @param Closure|string|object|null $job
248+ * @param JobShape $payload
249+ */
250+ public function addPayloadToTask (array $ payload , Task $ task , $ job ): Task
215251 {
216252 $ headers = $ this ->headers ($ payload );
217253
218254 if (! empty ($ this ->config ['app_engine ' ])) {
219255 $ path = \Safe \parse_url (route ('cloud-tasks.handle-task ' ), PHP_URL_PATH );
220256
257+ if (! is_string ($ path )) {
258+ throw new Exception ('Something went wrong parsing the route. ' );
259+ }
260+
221261 $ appEngineRequest = new AppEngineHttpRequest ;
222262 $ appEngineRequest ->setRelativeUri ($ path );
223263 $ appEngineRequest ->setHttpMethod (HttpMethod::POST );
224264 $ appEngineRequest ->setBody (json_encode ($ payload ));
225265 $ appEngineRequest ->setHeaders ($ headers );
226266
227- if (! empty ($ service = $ this ->config ['app_engine_service ' ])) {
267+ if (! empty ($ this ->config ['app_engine_service ' ])) {
228268 $ routing = new AppEngineRouting ;
229- $ routing ->setService ($ service );
269+ $ routing ->setService ($ this -> config [ ' app_engine_service ' ] );
230270 $ appEngineRequest ->setAppEngineRouting ($ routing );
231271 }
232272
@@ -239,7 +279,7 @@ public function addPayloadToTask(array $payload, Task $task, mixed $job): Task
239279 $ httpRequest ->setHeaders ($ headers );
240280
241281 $ token = new OidcToken ;
242- $ token ->setServiceAccountEmail ($ this ->config ['service_account_email ' ]);
282+ $ token ->setServiceAccountEmail ($ this ->config ['service_account_email ' ] ?? '' );
243283 $ httpRequest ->setOidcToken ($ token );
244284 $ task ->setHttpRequest ($ httpRequest );
245285 }
@@ -267,7 +307,9 @@ public function release(CloudTasksJob $job, int $delay = 0): void
267307 );
268308 }
269309
270- /** @param string|object $job */
310+ /**
311+ * @param Closure|string|object|null $job
312+ */
271313 public function getHandler (mixed $ job ): string
272314 {
273315 if (static ::$ handlerUrlCallback ) {
@@ -280,11 +322,11 @@ public function getHandler(mixed $job): string
280322
281323 $ handler = rtrim ($ this ->config ['handler ' ], '/ ' );
282324
283- if (str_ends_with ($ handler , '/ ' .config ('cloud-tasks.uri ' ))) {
325+ if (str_ends_with ($ handler , '/ ' .config ()-> string ( 'cloud-tasks.uri ' ))) {
284326 return $ handler ;
285327 }
286328
287- return $ handler .'/ ' .config ('cloud-tasks.uri ' );
329+ return $ handler .'/ ' .config ()-> string ( 'cloud-tasks.uri ' );
288330 }
289331
290332 /**
@@ -299,4 +341,19 @@ private function headers(mixed $payload): array
299341
300342 return (static ::$ taskHeadersCallback )($ payload );
301343 }
344+
345+ /**
346+ * @param Closure|string|JobBeforeDispatch $job
347+ */
348+ private function getQueueForJob (mixed $ job ): string
349+ {
350+ if (is_object ($ job ) && ! $ job instanceof Closure) {
351+ /** @var JobBeforeDispatch $job */
352+ if (! empty ($ job ->queue )) {
353+ return $ job ->queue ;
354+ }
355+ }
356+
357+ return $ this ->config ['queue ' ];
358+ }
302359}
0 commit comments