Skip to content

Commit 9ecafb6

Browse files
committed
wip
1 parent 77c7545 commit 9ecafb6

File tree

8 files changed

+134
-87
lines changed

8 files changed

+134
-87
lines changed

src/CloudTasksApi.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* @method static Task createTask(string $queueName, Task $task)
1212
* @method static void deleteTask(string $taskName)
1313
* @method static Task getTask(string $taskName)
14+
* @method static bool exists(string $taskName)
1415
*/
1516
class CloudTasksApi extends Facade
1617
{

src/CloudTasksApiConcrete.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Stackkit\LaravelGoogleCloudTasksQueue;
66

7+
use Google\ApiCore\ApiException;
78
use Google\Cloud\Tasks\V2\Client\CloudTasksClient;
89
use Google\Cloud\Tasks\V2\CreateTaskRequest;
910
use Google\Cloud\Tasks\V2\DeleteTaskRequest;
@@ -17,6 +18,9 @@ public function __construct(private readonly CloudTasksClient $client)
1718
//
1819
}
1920

21+
/**
22+
* @throws ApiException
23+
*/
2024
public function createTask(string $queueName, Task $task): Task
2125
{
2226
return $this->client->createTask(new CreateTaskRequest([
@@ -25,17 +29,40 @@ public function createTask(string $queueName, Task $task): Task
2529
]));
2630
}
2731

32+
/**
33+
* @throws ApiException
34+
*/
2835
public function deleteTask(string $taskName): void
2936
{
3037
$this->client->deleteTask(new DeleteTaskRequest([
3138
'name' => $taskName,
3239
]));
3340
}
3441

42+
/**
43+
* @throws ApiException
44+
*/
3545
public function getTask(string $taskName): Task
3646
{
3747
return $this->client->getTask(new GetTaskRequest([
3848
'name' => $taskName,
3949
]));
4050
}
51+
52+
public function exists(string $taskName): bool
53+
{
54+
try {
55+
$this->getTask($taskName);
56+
57+
return true;
58+
} catch (ApiException $e) {
59+
if ($e->getStatus() === 'NOT_FOUND') {
60+
return false;
61+
}
62+
63+
report($e);
64+
}
65+
66+
return false;
67+
}
4168
}

src/CloudTasksApiContract.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@ public function createTask(string $queueName, Task $task): Task;
1313
public function deleteTask(string $taskName): void;
1414

1515
public function getTask(string $taskName): Task;
16+
17+
public function exists(string $taskName): bool;
1618
}

src/CloudTasksApiFake.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ public function getTask(string $taskName): Task
3232
->setName($taskName);
3333
}
3434

35+
public function exists(string $taskName): bool
36+
{
37+
foreach ($this->createdTasks as $createdTask) {
38+
if ($createdTask['task']->getName() === $taskName) {
39+
return ! in_array($taskName, $this->deletedTasks);
40+
}
41+
}
42+
43+
return false;
44+
}
45+
3546
public function assertTaskDeleted(string $taskName): void
3647
{
3748
Assert::assertTrue(

src/CloudTasksJob.php

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
namespace Stackkit\LaravelGoogleCloudTasksQueue;
66

7+
use Exception;
78
use Illuminate\Container\Container;
89
use Illuminate\Contracts\Queue\Job as JobContract;
910
use Illuminate\Queue\Jobs\Job as LaravelJob;
11+
use Safe\Exceptions\JsonException;
1012
use Stackkit\LaravelGoogleCloudTasksQueue\Events\JobReleased;
1113

1214
use function Safe\json_encode;
@@ -15,43 +17,36 @@ class CloudTasksJob extends LaravelJob implements JobContract
1517
{
1618
protected $container;
1719

18-
private CloudTasksQueue $cloudTasksQueue;
20+
private CloudTasksQueue $driver;
1921

2022
public array $job;
2123

2224
protected $connectionName;
2325

2426
protected $queue;
2527

26-
/**
27-
* @param array $job
28-
* @param string $connectionName
29-
* @param string $queue
30-
*/
31-
public function __construct(Container $container, CloudTasksQueue $cloudTasksQueue, $job, $connectionName, $queue)
28+
public function __construct(
29+
Container $container,
30+
CloudTasksQueue $driver,
31+
array $job,
32+
string $connectionName,
33+
string $queue)
3234
{
3335
$this->container = $container;
34-
$this->cloudTasksQueue = $cloudTasksQueue;
36+
$this->driver = $driver;
3537
$this->job = $job;
3638
$this->connectionName = $connectionName;
3739
$this->queue = $queue;
3840
}
3941

40-
public function job(): array
41-
{
42-
return $this->job;
43-
}
44-
4542
public function getJobId(): string
4643
{
47-
return $this->job['uuid'];
48-
}
49-
50-
public function uuid(): string
51-
{
52-
return $this->job['uuid'];
44+
return $this->uuid() ?? throw new Exception();
5345
}
5446

47+
/**
48+
* @throws JsonException
49+
*/
5550
public function getRawBody(): string
5651
{
5752
return json_encode($this->job);
@@ -91,7 +86,7 @@ public function delete(): void
9186

9287
parent::delete();
9388

94-
$this->cloudTasksQueue->delete($this);
89+
$this->driver->delete($this);
9590
}
9691

9792
public function hasError(): bool
@@ -103,7 +98,7 @@ public function release($delay = 0): void
10398
{
10499
parent::release($delay);
105100

106-
$this->cloudTasksQueue->release($this, $delay);
101+
$this->driver->release($this, $delay);
107102

108103
if (! data_get($this->job, 'internal.errored')) {
109104
app('events')->dispatch(new JobReleased($this->getConnectionName(), $this, $delay));

src/CloudTasksQueue.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,10 @@ public function getHandler(): string
262262

263263
$handler = rtrim($this->config['handler'], '/');
264264

265-
return match (true) {
266-
! str_ends_with($handler, '/handle-task') => $handler.'/handle-task',
267-
default => $this->config['handler'],
268-
};
265+
if (str_ends_with($handler, '/handle-task')) {
266+
return $handler;
267+
}
268+
269+
return $handler.'/handle-task';
269270
}
270271
}

src/IncomingTask.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Stackkit\LaravelGoogleCloudTasksQueue;
6+
7+
use Safe\Exceptions\JsonException;
8+
use function Safe\json_decode;
9+
10+
class IncomingTask
11+
{
12+
private function __construct(private readonly array $task)
13+
{
14+
//
15+
}
16+
17+
public static function fromJson(string $payload): self
18+
{
19+
try {
20+
$decode = json_decode($payload, assoc: true);
21+
22+
return new self(is_array($decode) ? $decode : []);
23+
} catch (JsonException) {
24+
return new self([]);
25+
}
26+
}
27+
28+
public function isEmpty(): bool
29+
{
30+
return $this->task === [];
31+
}
32+
33+
public function connection(): string
34+
{
35+
return $this->task['internal']['connection'];
36+
}
37+
38+
public function queue(): string
39+
{
40+
return $this->task['internal']['queue'];
41+
}
42+
43+
public function taskName(): string
44+
{
45+
return $this->task['internal']['taskName'];
46+
}
47+
48+
public function toArray(): array
49+
{
50+
return $this->task;
51+
}
52+
}

src/TaskHandler.php

Lines changed: 20 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,93 +4,51 @@
44

55
namespace Stackkit\LaravelGoogleCloudTasksQueue;
66

7-
use Google\ApiCore\ApiException;
87
use Google\Cloud\Tasks\V2\Client\CloudTasksClient;
98
use Illuminate\Container\Container;
109
use Illuminate\Queue\Worker;
1110
use Illuminate\Queue\WorkerOptions;
12-
use Throwable;
13-
14-
use function Safe\json_decode;
1511

1612
class TaskHandler
1713
{
18-
/**
19-
* @var array
20-
*/
21-
private $config;
22-
23-
/**
24-
* @var CloudTasksClient
25-
*/
26-
private $client;
27-
28-
/**
29-
* @var CloudTasksQueue
30-
*/
31-
private $queue;
32-
33-
public function __construct(CloudTasksClient $client)
14+
private array $config;
15+
16+
public function __construct(private readonly CloudTasksClient $client)
3417
{
35-
$this->client = $client;
18+
//
3619
}
3720

3821
public function handle(?string $task = null): void
3922
{
40-
$task = json_decode((string) $task ?: request()->getContent(), assoc: true);
23+
$task = IncomingTask::fromJson($task ?: request()->getContent());
4124

42-
$this->config = config('queue.connections.'.$task['internal']['connection']);
43-
44-
$this->guard($task);
25+
if ($task->isEmpty()) {
26+
abort(422, 'Invalid task payload');
27+
}
4528

46-
$this->handleTask($task);
47-
}
29+
if (! CloudTasksApi::exists($task->taskName())) {
30+
abort(404);
31+
}
4832

49-
private function guard(array $task): void
50-
{
51-
$appEngine = ! empty($this->config['app_engine']);
33+
$config = config('queue.connections.'.$task->connection());
5234

53-
if ($appEngine) {
54-
// https://cloud.google.com/tasks/docs/creating-appengine-handlers#reading_task_request_headers
55-
// "If your request handler finds any of the headers listed above, it can trust
56-
// that the request is a Cloud Tasks request."
57-
abort_if(empty(request()->header('X-AppEngine-TaskName')), 404);
35+
$this->config = is_array($config) ? $config : [];
5836

59-
return;
60-
}
61-
62-
if (config('cloud-tasks.disable_security_key_verification') !== true) {
63-
abort_if(decrypt($task['internal']['securityKey']) !== $task['uuid'], 404);
64-
}
37+
$this->run($task);
6538
}
6639

67-
private function handleTask(array $task): void
40+
private function run(IncomingTask $task): void
6841
{
69-
$queue = new CloudTasksQueue(
70-
config: $this->config,
71-
client: $this->client,
72-
);
73-
74-
$queue->setConnectionName($task['internal']['connection']);
42+
$queue = tap(new CloudTasksQueue($this->config, $this->client))->setConnectionName($task->connection());
7543

7644
$job = new CloudTasksJob(
7745
container: Container::getInstance(),
78-
cloudTasksQueue: $queue,
79-
job: $task,
80-
connectionName: $task['internal']['connection'],
81-
queue: $task['internal']['queue'],
46+
driver: $queue,
47+
job: $task->toArray(),
48+
connectionName: $task->connection(),
49+
queue: $task->queue(),
8250
);
8351

84-
try {
85-
CloudTasksApi::getTask($task['internal']['taskName']);
86-
} catch (Throwable $e) {
87-
if ($e instanceof ApiException && in_array($e->getStatus(), ['NOT_FOUND', 'PRECONDITION_FAILED'])) {
88-
abort(404);
89-
}
90-
91-
throw $e;
92-
}
93-
9452
$job->setAttempts($job->attempts() + 1);
9553

9654
tap(app('queue.worker'), fn (Worker $worker) => $worker->process(

0 commit comments

Comments
 (0)