Skip to content

Commit e6a795d

Browse files
committed
Refactor & cleanup
1 parent 0728bb5 commit e6a795d

File tree

6 files changed

+55
-195
lines changed

6 files changed

+55
-195
lines changed

src/CloudTasksJob.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,8 @@ public function release($delay = 0): void
100100

101101
$this->cloudTasksQueue->release($this, $delay);
102102

103-
$properties = TaskHandler::getCommandProperties($this->job['data']['command']);
104-
$connection = $properties['connection'] ?? config('queue.default');
105-
106103
if (! data_get($this->job, 'internal.errored')) {
107-
app('events')->dispatch(new JobReleased($connection, $this, $delay));
104+
app('events')->dispatch(new JobReleased($this->getConnectionName(), $this, $delay));
108105
}
109106
}
110107
}

src/CloudTasksQueue.php

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,13 @@ protected function pushToCloudTasks($queue, $payload, $delay = 0)
113113

114114
$payload = json_decode($payload, true);
115115

116-
// Since 3.x tasks are released back onto the queue after an exception has
117-
// been thrown. This means we lose the native [X-CloudTasks-TaskRetryCount] header
118-
// value and need to manually set and update the number of times a task has been attempted.
119-
$payload = $this->withAttempts($payload);
120-
121-
$payload = $this->withQueueName($payload, $queue);
122-
123116
$task = new Task();
124117
$task->setName($this->taskName($queue, $payload));
125118

119+
$payload = $this->withAttempts($payload);
120+
$payload = $this->withQueueName($payload, $queue);
126121
$payload = $this->withTaskName($payload, $task->getName());
122+
$payload = $this->withConnectionName($payload, $this->getConnectionName());
127123

128124
if (! empty($this->config['app_engine'])) {
129125
$path = \Safe\parse_url(route('cloud-tasks.handle-task'), PHP_URL_PATH);
@@ -218,6 +214,13 @@ private function withTaskName(array $payload, string $taskName): array
218214
return $payload;
219215
}
220216

217+
private function withConnectionName(array $payload, string $connectionName): array
218+
{
219+
$payload['internal']['connection'] = $connectionName;
220+
221+
return $payload;
222+
}
223+
221224
/**
222225
* Pop the next job off of the queue.
223226
*

src/TaskHandler.php

Lines changed: 24 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77
use Google\ApiCore\ApiException;
88
use Google\Cloud\Tasks\V2\Client\CloudTasksClient;
99
use Illuminate\Container\Container;
10-
use Illuminate\Contracts\Encryption\Encrypter;
10+
use Illuminate\Queue\Worker;
1111
use Illuminate\Queue\WorkerOptions;
12-
use Illuminate\Support\Str;
13-
use Illuminate\Validation\ValidationException;
14-
use Safe\Exceptions\JsonException;
12+
use Throwable;
1513

1614
use function Safe\json_decode;
1715

@@ -39,72 +37,15 @@ public function __construct(CloudTasksClient $client)
3937

4038
public function handle(?string $task = null): void
4139
{
42-
$task = $this->captureTask($task);
40+
$task = json_decode((string) $task ?: request()->getContent(), assoc: true);
4341

44-
$this->loadQueueConnectionConfiguration($task);
45-
46-
$this->setQueue();
42+
$this->config = config('queue.connections.'.$task['internal']['connection']);
4743

4844
$this->guard();
4945

5046
$this->handleTask($task);
5147
}
5248

53-
/**
54-
* @param string|array|null $task
55-
*
56-
* @throws JsonException
57-
*/
58-
private function captureTask($task): array
59-
{
60-
$task = $task ?: (string) (request()->getContent());
61-
62-
try {
63-
$array = json_decode($task, true);
64-
} catch (JsonException $e) {
65-
$array = [];
66-
}
67-
68-
$validator = validator([
69-
'json' => $task,
70-
'task' => $array,
71-
], [
72-
'json' => 'required|json',
73-
'task' => 'required|array',
74-
'task.data' => 'required|array',
75-
]);
76-
77-
try {
78-
$validator->validate();
79-
} catch (ValidationException $e) {
80-
if (config('app.debug')) {
81-
throw $e;
82-
} else {
83-
abort(404);
84-
}
85-
}
86-
87-
return json_decode($task, true);
88-
}
89-
90-
private function loadQueueConnectionConfiguration(array $task): void
91-
{
92-
$command = self::getCommandProperties($task['data']['command']);
93-
$connection = $command['connection'] ?? config('queue.default');
94-
$baseConfig = config('queue.connections.'.$connection);
95-
$config = (new CloudTasksConnector())->connect($baseConfig)->config;
96-
97-
// The connection name from the config may not be the actual connection name
98-
$config['connection'] = $connection;
99-
100-
$this->config = $config;
101-
}
102-
103-
private function setQueue(): void
104-
{
105-
$this->queue = new CloudTasksQueue($this->config, $this->client);
106-
}
107-
10849
private function guard(): void
10950
{
11051
$appEngine = ! empty($this->config['app_engine']);
@@ -121,18 +62,25 @@ private function guard(): void
12162

12263
private function handleTask(array $task): void
12364
{
65+
$queue = new CloudTasksQueue(
66+
config: $this->config,
67+
client: $this->client,
68+
);
69+
70+
$queue->setConnectionName($task['internal']['connection']);
71+
12472
$job = new CloudTasksJob(
125-
Container::getInstance(),
126-
$this->queue,
127-
$task,
128-
$this->config['connection'],
129-
$task['internal']['queue'],
73+
container: Container::getInstance(),
74+
cloudTasksQueue: $queue,
75+
job: $task,
76+
connectionName: $task['internal']['connection'],
77+
queue: $task['internal']['queue'],
13078
);
13179

13280
try {
133-
$apiTask = CloudTasksApi::getTask($task['internal']['taskName']);
134-
} catch (ApiException $e) {
135-
if (in_array($e->getStatus(), ['NOT_FOUND', 'PRECONDITION_FAILED'])) {
81+
CloudTasksApi::getTask($task['internal']['taskName']);
82+
} catch (Throwable $e) {
83+
if ($e instanceof ApiException && in_array($e->getStatus(), ['NOT_FOUND', 'PRECONDITION_FAILED'])) {
13684
abort(404);
13785
}
13886

@@ -141,23 +89,11 @@ private function handleTask(array $task): void
14189

14290
$job->setAttempts($job->attempts() + 1);
14391

144-
app('queue.worker')->process($this->config['connection'], $job, $this->getWorkerOptions());
145-
}
146-
147-
public static function getCommandProperties(string $command): array
148-
{
149-
if (Str::startsWith($command, 'O:')) {
150-
return (array) unserialize($command, ['allowed_classes' => false]);
151-
}
152-
153-
if (app()->bound(Encrypter::class)) {
154-
return (array) unserialize(
155-
app(Encrypter::class)->decrypt($command),
156-
['allowed_classes' => ['Illuminate\Support\Carbon']]
157-
);
158-
}
159-
160-
return [];
92+
tap(app('queue.worker'), fn (Worker $worker) => $worker->process(
93+
connectionName: $job->getConnectionName(),
94+
job: $job,
95+
options: $this->getWorkerOptions()
96+
));
16197
}
16298

16399
public function getWorkerOptions(): WorkerOptions

tests/QueueTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use Stackkit\LaravelGoogleCloudTasksQueue\Events\JobReleased;
2020
use Stackkit\LaravelGoogleCloudTasksQueue\LogFake;
2121
use Stackkit\LaravelGoogleCloudTasksQueue\OpenIdVerificator;
22-
use Stackkit\LaravelGoogleCloudTasksQueue\TaskHandler;
2322
use Tests\Support\FailingJob;
2423
use Tests\Support\FailingJobWithExponentialBackoff;
2524
use Tests\Support\JobThatWillBeReleased;
@@ -154,7 +153,7 @@ public function it_posts_the_task_the_correct_queue()
154153
// Assert
155154
CloudTasksApi::assertTaskCreated(function (Task $task, string $queueName): bool {
156155
$decoded = json_decode($task->getHttpRequest()->getBody(), true);
157-
$command = TaskHandler::getCommandProperties($decoded['data']['command']);
156+
$command = $this->getCommandProperties($decoded['data']['command']);
158157

159158
return $decoded['displayName'] === SimpleJob::class
160159
&& ($command['queue'] ?? null) === null
@@ -163,7 +162,7 @@ public function it_posts_the_task_the_correct_queue()
163162

164163
CloudTasksApi::assertTaskCreated(function (Task $task, string $queueName): bool {
165164
$decoded = json_decode($task->getHttpRequest()->getBody(), true);
166-
$command = TaskHandler::getCommandProperties($decoded['data']['command']);
165+
$command = $this->getCommandProperties($decoded['data']['command']);
167166

168167
return $decoded['displayName'] === FailingJob::class
169168
&& $command['queue'] === 'my-special-queue'

tests/TaskHandlerTest.php

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use Stackkit\LaravelGoogleCloudTasksQueue\CloudTasksException;
1717
use Stackkit\LaravelGoogleCloudTasksQueue\LogFake;
1818
use Stackkit\LaravelGoogleCloudTasksQueue\OpenIdVerificator;
19-
use Stackkit\LaravelGoogleCloudTasksQueue\TaskHandler;
2019
use Tests\Support\EncryptedJob;
2120
use Tests\Support\FailingJob;
2221
use Tests\Support\FailingJobWithMaxTries;
@@ -34,88 +33,6 @@ protected function setUp(): void
3433
CloudTasksApi::fake();
3534
}
3635

37-
/**
38-
* @test
39-
*
40-
* @testWith [true]
41-
* [false]
42-
*/
43-
public function it_returns_responses_for_empty_payloads($debug)
44-
{
45-
// Arrange
46-
config()->set('app.debug', $debug);
47-
48-
// Act
49-
$response = $this->postJson(action([TaskHandler::class, 'handle']));
50-
51-
// Assert
52-
if ($debug) {
53-
$response->assertJsonValidationErrors('task');
54-
} else {
55-
$response->assertNotFound();
56-
}
57-
}
58-
59-
/**
60-
* @test
61-
*
62-
* @testWith [true]
63-
* [false]
64-
*/
65-
public function it_returns_responses_for_invalid_json($debug)
66-
{
67-
// Arrange
68-
config()->set('app.debug', $debug);
69-
70-
// Act
71-
$response = $this->call(
72-
'POST',
73-
action([TaskHandler::class, 'handle']),
74-
[],
75-
[],
76-
[],
77-
[
78-
'HTTP_ACCEPT' => 'application/json',
79-
],
80-
'test',
81-
);
82-
83-
// Assert
84-
if ($debug) {
85-
$response->assertJsonValidationErrors('task');
86-
} else {
87-
$response->assertNotFound();
88-
}
89-
}
90-
91-
/**
92-
* @test
93-
*
94-
* @testWith ["{\"invalid\": \"data\"}"]
95-
* ["{\"data\": \"\"}"]
96-
* ["{\"data\": \"test\"}"]
97-
*/
98-
public function it_returns_responses_for_invalid_payloads(string $payload)
99-
{
100-
// Arrange
101-
102-
// Act
103-
$response = $this->call(
104-
'POST',
105-
action([TaskHandler::class, 'handle']),
106-
[],
107-
[],
108-
[],
109-
[
110-
'HTTP_ACCEPT' => 'application/json',
111-
],
112-
$payload,
113-
);
114-
115-
// Assert
116-
$response->assertJsonValidationErrors('task.data');
117-
}
118-
11936
/**
12037
* @test
12138
*/

tests/TestCase.php

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
use Google\ApiCore\ApiException;
1010
use Google\Cloud\Tasks\V2\Client\CloudTasksClient;
1111
use Google\Cloud\Tasks\V2\Task;
12+
use Illuminate\Contracts\Encryption\Encrypter;
1213
use Illuminate\Foundation\Testing\DatabaseTransactions;
1314
use Illuminate\Queue\Events\JobReleasedAfterException;
1415
use Illuminate\Support\Facades\DB;
1516
use Illuminate\Support\Facades\Event;
17+
use Illuminate\Support\Str;
1618
use Stackkit\LaravelGoogleCloudTasksQueue\Events\TaskCreated;
1719
use Stackkit\LaravelGoogleCloudTasksQueue\TaskHandler;
1820

@@ -134,16 +136,6 @@ public function dispatch($job)
134136
$payload = $request->getBody();
135137
$payloadAsArray = json_decode($payload, true);
136138
$task = $event->task;
137-
138-
[,,,,,,,$taskName] = explode('/', $task->getName());
139-
140-
if ($task->hasHttpRequest()) {
141-
request()->headers->set('X-Cloudtasks-Taskname', $taskName);
142-
}
143-
144-
if ($task->hasAppEngineHttpRequest()) {
145-
request()->headers->set('X-AppEngine-TaskName', $taskName);
146-
}
147139
});
148140

149141
dispatch($job);
@@ -271,4 +263,20 @@ public function withTaskType(string $taskType): void
271263
break;
272264
}
273265
}
266+
267+
public static function getCommandProperties(string $command): array
268+
{
269+
if (Str::startsWith($command, 'O:')) {
270+
return (array) unserialize($command, ['allowed_classes' => false]);
271+
}
272+
273+
if (app()->bound(Encrypter::class)) {
274+
return (array) unserialize(
275+
app(Encrypter::class)->decrypt($command),
276+
['allowed_classes' => ['Illuminate\Support\Carbon']]
277+
);
278+
}
279+
280+
return [];
281+
}
274282
}

0 commit comments

Comments
 (0)