Skip to content

Commit 52ae5ea

Browse files
Merge pull request #139 from aaajeetee/4.x-dev
[4.x dev] Added support for handler-url and headers per job
2 parents 3ffdee8 + 4b224ae commit 52ae5ea

File tree

4 files changed

+113
-29
lines changed

4 files changed

+113
-29
lines changed

README.md

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,26 +102,44 @@ Please check the table below on what the values mean and what their value should
102102

103103
#### Passing headers to a task
104104

105-
You can pass headers to a task by using the `withHeaders` method on the queue connection.
105+
You can pass headers to a task by using the `setTaskHeadersUsing` method on the `CloudTasksQueue` class.
106106

107107
```php
108-
use Illuminate\Queue\Queue;
108+
use Stackkit\LaravelGoogleCloudTasksQueue\CloudTasksQueue;
109109

110-
Queue::connection()->setTaskHeaders([
110+
CloudTasksQueue::setTaskHeadersUsing(static fn() => [
111111
'X-My-Header' => 'My-Value',
112112
]);
113113
```
114114

115-
If necessary, the current job being dispatched is also available:
115+
If necessary, the current payload being dispatched is also available:
116116

117117
```php
118-
use Illuminate\Queue\Queue;
118+
use Stackkit\LaravelGoogleCloudTasksQueue\CloudTasksQueue;
119119

120-
Queue::connection()->setTaskHeaders(fn (array $job) => [
121-
'X-My-Header' => $job['displayName']
120+
CloudTasksQueue::setTaskHeadersUsing(static fn(array $payload) => [
121+
'X-My-Header' => $payload['displayName'],
122122
]);
123123
```
124124

125+
#### Configure task handler url
126+
127+
You can set the handler url for a task by using the `configureHandlerUrlUsing` method on the `CloudTasksQueue` class.
128+
129+
```php
130+
use Stackkit\LaravelGoogleCloudTasksQueue\CloudTasksQueue;
131+
132+
CloudTasksQueue::configureHandlerUrlUsing(static fn() => 'https://example.com/my-url');
133+
```
134+
135+
If necessary, the current job being dispatched is also available:
136+
137+
```php
138+
use Stackkit\LaravelGoogleCloudTasksQueue\CloudTasksQueue;
139+
140+
CloudTasksQueue::configureHandlerUrlUsing(static fn(MyJob $job) => 'https://example.com/my-url/' . $job->something());
141+
```
142+
125143
<details>
126144
<summary>
127145
How it works & Differences

src/CloudTasksQueue.php

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,33 @@
2424

2525
class CloudTasksQueue extends LaravelQueue implements QueueContract
2626
{
27-
private Closure|array $headers = [];
27+
private static ?Closure $handlerUrlCallback = null;
28+
private static ?Closure $taskHeadersCallback = null;
2829

2930
public function __construct(public array $config, public CloudTasksClient $client, public $dispatchAfterCommit = false)
3031
{
3132
//
3233
}
34+
35+
public static function configureHandlerUrlUsing(Closure $callback): void
36+
{
37+
static::$handlerUrlCallback = $callback;
38+
}
39+
40+
public static function forgetHandlerUrlCallback(): void
41+
{
42+
self::$handlerUrlCallback = null;
43+
}
44+
45+
public static function setTaskHeadersUsing(Closure $callback): void
46+
{
47+
static::$taskHeadersCallback = $callback;
48+
}
49+
50+
public static function forgetTaskHeadersCallback(): void
51+
{
52+
self::$taskHeadersCallback = null;
53+
}
3354

3455
/**
3556
* Get the size of the queue.
@@ -57,8 +78,8 @@ public function push($job, $data = '', $queue = null)
5778
$this->createPayload($job, $queue, $data),
5879
$queue,
5980
null,
60-
function ($payload, $queue) {
61-
return $this->pushRaw($payload, $queue);
81+
function ($payload, $queue) use ($job) {
82+
return $this->pushRaw($payload, $queue, ['job' => $job]);
6283
}
6384
);
6485
}
@@ -73,8 +94,9 @@ function ($payload, $queue) {
7394
public function pushRaw($payload, $queue = null, array $options = [])
7495
{
7596
$delay = ! empty($options['delay']) ? $options['delay'] : 0;
97+
$job = $options['job'] ?? null;
7698

77-
return $this->pushToCloudTasks($queue, $payload, $delay);
99+
return $this->pushToCloudTasks($queue, $payload, $delay, $job);
78100
}
79101

80102
/**
@@ -93,8 +115,8 @@ public function later($delay, $job, $data = '', $queue = null)
93115
$this->createPayload($job, $queue, $data),
94116
$queue,
95117
$delay,
96-
function ($payload, $queue, $delay) {
97-
return $this->pushToCloudTasks($queue, $payload, $delay);
118+
function ($payload, $queue, $delay) use ($job) {
119+
return $this->pushToCloudTasks($queue, $payload, $delay, $job);
98120
}
99121
);
100122
}
@@ -105,9 +127,10 @@ function ($payload, $queue, $delay) {
105127
* @param string|null $queue
106128
* @param string $payload
107129
* @param \DateTimeInterface|\DateInterval|int $delay
130+
* @param string|object $job
108131
* @return string
109132
*/
110-
protected function pushToCloudTasks($queue, $payload, $delay = 0)
133+
protected function pushToCloudTasks($queue, $payload, $delay, mixed $job)
111134
{
112135
$queue = $queue ?: $this->config['queue'];
113136

@@ -122,7 +145,7 @@ protected function pushToCloudTasks($queue, $payload, $delay = 0)
122145
connectionName: $this->getConnectionName(),
123146
);
124147

125-
$this->addPayloadToTask($payload, $task);
148+
$this->addPayloadToTask($payload, $task, $job);
126149

127150
// The deadline for requests sent to the app. If the app does not respond by
128151
// this deadline then the request is cancelled and the attempt is marked as
@@ -173,9 +196,10 @@ private function enrichPayloadWithInternalData(
173196
return $payload;
174197
}
175198

176-
public function addPayloadToTask(array $payload, Task $task): Task
199+
/** @param string|object $job */
200+
public function addPayloadToTask(array $payload, Task $task, mixed $job): Task
177201
{
178-
$headers = value($this->headers, $payload) ?: [];
202+
$headers = $this->headers($payload);
179203

180204
if (! empty($this->config['app_engine'])) {
181205
$path = \Safe\parse_url(route('cloud-tasks.handle-task'), PHP_URL_PATH);
@@ -195,7 +219,7 @@ public function addPayloadToTask(array $payload, Task $task): Task
195219
$task->setAppEngineHttpRequest($appEngineRequest);
196220
} else {
197221
$httpRequest = new HttpRequest();
198-
$httpRequest->setUrl($this->getHandler());
222+
$httpRequest->setUrl($this->getHandler($job));
199223
$httpRequest->setBody(json_encode($payload));
200224
$httpRequest->setHttpMethod(HttpMethod::POST);
201225
$httpRequest->setHeaders($headers);
@@ -225,12 +249,17 @@ public function release(CloudTasksJob $job, int $delay = 0): void
225249
$this->pushRaw(
226250
payload: $job->getRawBody(),
227251
queue: $job->getQueue(),
228-
options: ['delay' => $delay]
252+
options: ['delay' => $delay, 'job' => $job],
229253
);
230254
}
231255

232-
public function getHandler(): string
256+
/** @param string|object $job */
257+
public function getHandler(mixed $job): string
233258
{
259+
if (static::$handlerUrlCallback) {
260+
return (static::$handlerUrlCallback)($job);
261+
}
262+
234263
if (empty($this->config['handler'])) {
235264
$this->config['handler'] = request()->getSchemeAndHttpHost();
236265
}
@@ -244,8 +273,16 @@ public function getHandler(): string
244273
return $handler.'/'.config('cloud-tasks.uri');
245274
}
246275

247-
public function setTaskHeaders(Closure|array $headers): void
276+
/**
277+
* @param array<string, mixed> $payload
278+
* @return array<string, mixed>
279+
*/
280+
private function headers(mixed $payload): array
248281
{
249-
$this->headers = $headers;
282+
if (!static::$taskHeadersCallback) {
283+
return [];
284+
}
285+
286+
return (static::$taskHeadersCallback)($payload);
250287
}
251288
}

tests/QueueTest.php

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
use Illuminate\Support\Facades\Event;
1616
use Illuminate\Support\Facades\Queue;
1717
use Illuminate\Support\Str;
18+
use Override;
1819
use PHPUnit\Framework\Attributes\Test;
1920
use Stackkit\LaravelGoogleCloudTasksQueue\CloudTasksApi;
21+
use Stackkit\LaravelGoogleCloudTasksQueue\CloudTasksQueue;
2022
use Stackkit\LaravelGoogleCloudTasksQueue\Events\JobReleased;
2123
use Tests\Support\FailingJob;
2224
use Tests\Support\FailingJobWithExponentialBackoff;
@@ -28,6 +30,15 @@
2830

2931
class QueueTest extends TestCase
3032
{
33+
#[Override]
34+
protected function tearDown(): void
35+
{
36+
parent::tearDown();
37+
38+
CloudTasksQueue::forgetHandlerUrlCallback();
39+
CloudTasksQueue::forgetTaskHeadersCallback();
40+
}
41+
3142
#[Test]
3243
public function a_http_request_with_the_handler_url_is_made()
3344
{
@@ -59,7 +70,7 @@ public function it_posts_to_the_handler()
5970
}
6071

6172
#[Test]
62-
public function it_posts_to_the_correct_handler_url()
73+
public function it_posts_to_the_configured_handler_url()
6374
{
6475
// Arrange
6576
$this->setConfigValue('handler', 'https://docker.for.mac.localhost:8081');
@@ -74,6 +85,25 @@ public function it_posts_to_the_correct_handler_url()
7485
});
7586
}
7687

88+
#[Test]
89+
public function it_posts_to_the_callback_handler_url()
90+
{
91+
// Arrange
92+
$this->setConfigValue('handler', 'https://docker.for.mac.localhost:8081');
93+
CloudTasksApi::fake();
94+
CloudTasksQueue::configureHandlerUrlUsing(static fn(SimpleJob $job) => 'https://example.com/api/my-custom-route?job=' . $job->id);
95+
96+
// Act
97+
$job = new SimpleJob();
98+
$job->id = 1;
99+
$this->dispatch($job);
100+
101+
// Assert
102+
CloudTasksApi::assertTaskCreated(function (Task $task): bool {
103+
return $task->getHttpRequest()->getUrl() === 'https://example.com/api/my-custom-route?job=1';
104+
});
105+
}
106+
77107
#[Test]
78108
public function it_posts_the_serialized_job_payload_to_the_handler()
79109
{
@@ -459,7 +489,7 @@ public function headers_can_be_added_to_the_task()
459489
CloudTasksApi::fake();
460490

461491
// Act
462-
Queue::connection()->setTaskHeaders([
492+
CloudTasksQueue::setTaskHeadersUsing(static fn() => [
463493
'X-MyHeader' => 'MyValue',
464494
]);
465495

@@ -478,11 +508,9 @@ public function headers_can_be_added_to_the_task_with_job_context()
478508
CloudTasksApi::fake();
479509

480510
// Act
481-
Queue::connection()->setTaskHeaders(function (array $payload) {
482-
return [
483-
'X-MyHeader' => $payload['displayName'],
484-
];
485-
});
511+
CloudTasksQueue::setTaskHeadersUsing(static fn(array $payload) => [
512+
'X-MyHeader' => $payload['displayName'],
513+
]);
486514

487515
$this->dispatch((new SimpleJob()));
488516

tests/Support/SimpleJob.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class SimpleJob implements ShouldQueue
1515
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
1616

1717
public $tries = 3;
18+
public $id = 0;
1819

1920
/**
2021
* Create a new job instance.

0 commit comments

Comments
 (0)