Skip to content

Commit c4664b3

Browse files
Merge pull request #76 from stackkit/master
3.x
2 parents 33638b2 + b0fdb29 commit c4664b3

34 files changed

+1289
-147
lines changed

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,41 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## 3.3.1 - 2022-10-22
8+
9+
**Fixed**
10+
11+
- Fixes [#73](https://github.com/stackkit/laravel-google-cloud-tasks-queue/issues/73) Cannot access protected property Illuminate\Queue\Jobs\SyncJob::$job
12+
13+
## 3.3.0 - 2022-10-15
14+
15+
**Added**
16+
17+
- Jobs can now be released back onto the queue.
18+
19+
## 3.2.1 - 2022-09-02
20+
21+
**Fixed**
22+
23+
- Jobs were dispatched before a DB commit if `after_commit` or `afterCommit()` was used. This has now been corrected.
24+
25+
**Added**
26+
27+
- Request validation for the TaskHandler endpoint.
28+
29+
## 3.2.0 - 2022-08-13
30+
31+
**Added**
32+
33+
- Added support for jobs that use the `Illuminate\Contracts\Queue\ShouldBeEncrypted` contract
34+
35+
## 3.1.4 - 2022-06-24
36+
37+
**Fixed**
38+
39+
- Fixed usage of incorrect header to set count retries ([#55](https://github.com/stackkit/laravel-google-cloud-tasks-queue/discussions/55))
40+
- Fix getRetryUntilTimestamp not working due to incomplete task name ([#56](https://github.com/stackkit/laravel-google-cloud-tasks-queue/discussions/56))
41+
742
## 3.1.3 - 2022-06-19
843

944
**Fixed**

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Please check the table below for supported Laravel and PHP versions:
5656
// does not respond by this deadline then the request is cancelled and the attempt
5757
// is marked as a DEADLINE_EXCEEDED failure.
5858
'dispatch_deadline' => null,
59+
'backoff' => 0,
5960
],
6061
```
6162

@@ -79,13 +80,19 @@ Please check the table below on what the values mean and what their value should
7980
</details>
8081
<details>
8182
<summary>
82-
How it works
83+
How it works & Differences
8384
</summary>
8485
<br>
8586
Using Cloud Tasks as a Laravel queue driver is fundamentally different than other Laravel queue drivers, like Redis.
8687

8788
Typically a Laravel queue has a worker that listens to incoming jobs using the `queue:work` / `queue:listen` command.
8889
With Cloud Tasks, this is not the case. Instead, Cloud Tasks will schedule the job for you and make an HTTP request to your application with the job payload. There is no need to run a `queue:work/listen` command.
90+
91+
#### Good to know
92+
93+
- The "Min backoff" and "Max backoff" options in Cloud Tasks are ignored. This is intentional: Laravel has its own backoff feature (which is more powerful than what Cloud Tasks offers) and therefore I have chosen that over the Cloud Tasks one.
94+
- Similarly to the backoff feature, I have also chosen to let the package do job retries the 'Laravel way'. In Cloud Tasks, when a task throws an exception, Cloud Tasks will decide for itself when to retry the task (based on the backoff values). It will also manage its own state and knows how many times a task has been retried. This is different from Laravel. In typical Laravel queues, when a job throws an exception, the job is deleted and released back onto the queue. In order to support Laravel's backoff feature, this package must behave the same way about job retries.
95+
8996
</details>
9097
<details>
9198
<summary>Dashboard (beta)</summary>

composer.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,23 @@
3636
"Stackkit\\LaravelGoogleCloudTasksQueue\\CloudTasksServiceProvider"
3737
]
3838
}
39+
},
40+
"scripts": {
41+
"l9": [
42+
"composer require laravel/framework:9.* orchestra/testbench:7.* --no-interaction --no-update",
43+
"composer update --prefer-stable --prefer-dist --no-interaction --no-suggest"
44+
],
45+
"l8": [
46+
"composer require laravel/framework:8.* orchestra/testbench:6.* --no-interaction --no-update",
47+
"composer update --prefer-stable --prefer-dist --no-interaction --no-suggest"
48+
],
49+
"l7": [
50+
"composer require laravel/framework:7.* orchestra/testbench:5.* --no-interaction --no-update",
51+
"composer update --prefer-stable --prefer-dist --no-interaction --no-suggest"
52+
],
53+
"l6": [
54+
"composer require laravel/framework:6.* orchestra/testbench:4.* --no-interaction --no-update",
55+
"composer update --prefer-stable --prefer-dist --no-interaction --no-suggest"
56+
]
3957
}
4058
}

dashboard/dist/assets/index.1002db9a.css renamed to dashboard/dist/assets/index.d8eef428.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dashboard/dist/assets/index.5a46c6a0.js renamed to dashboard/dist/assets/index.ea68d73f.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dashboard/dist/crossword.png

-42.7 KB
Binary file not shown.

dashboard/dist/dot-grid.png

-25.4 KB
Binary file not shown.

dashboard/dist/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
<link rel="icon" href="/favicon.ico" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>Vite App</title>
8-
<script type="module" crossorigin src="/assets/index.5a46c6a0.js"></script>
8+
<script type="module" crossorigin src="/assets/index.ea68d73f.js"></script>
99
<link rel="modulepreload" href="/assets/vendor.433de25e.js">
10-
<link rel="stylesheet" href="/assets/index.1002db9a.css">
10+
<link rel="stylesheet" href="/assets/index.d8eef428.css">
1111
</head>
1212
<body class="bg-gray-100">
1313
<div id="app"></div>

dashboard/dist/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"index.html": {
3-
"file": "assets/index.5a46c6a0.js",
3+
"file": "assets/index.ea68d73f.js",
44
"src": "index.html",
55
"isEntry": true,
66
"imports": [
77
"_vendor.433de25e.js"
88
],
99
"css": [
10-
"assets/index.1002db9a.css"
10+
"assets/index.d8eef428.css"
1111
]
1212
},
1313
"_vendor.433de25e.js": {

dashboard/dist/pw_maze_white.png

-600 Bytes
Binary file not shown.

dashboard/src/components/Status.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function ucfirst(input) {
3131
.task-queued, .task-scheduled {
3232
@apply bg-gray-100 text-gray-500
3333
}
34-
.task-running {
34+
.task-running, .task-released {
3535
@apply bg-blue-100 text-blue-800
3636
}
3737
</style>

dashboard/src/components/Task.vue

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const titles = {
2727
successful: 'Successful',
2828
error: 'An error occurred',
2929
failed: 'Failed permanently',
30+
released: 'Released',
3031
}
3132
</script>
3233

@@ -60,6 +61,13 @@ const titles = {
6061
Scheduled: {{ event['scheduled_at'] }} (UTC)
6162
</span>
6263
</div>
64+
<div v-if="event['delay']">
65+
<span
66+
class="bg-gray-200 text-gray-800 text-xs font-medium mr-2 inline-block mb-1 px-1.5 py-0.5 rounded dark:bg-blue-200 dark:text-blue-800"
67+
>
68+
Delay: {{ event['delay'] }} seconds
69+
</span>
70+
</div>
6371
</h3>
6472
<Popper
6573
:content="event.datetime"

phpunit.xml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@
1010
stopOnFailure="false">
1111
<testsuites>
1212
<testsuite name="Testsuite">
13-
<file>./tests/ConfigTest.php</file>
14-
<file>./tests/TaskHandlerTest.php</file>
15-
<file>./tests/CloudTasksApiTest.php</file>
16-
<file>./tests/CloudTasksDashboardTest.php</file>
13+
<directory suffix="Test.php">./tests</directory>
1714
</testsuite>
1815
</testsuites>
1916
<php>

src/CloudTasksApiFake.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,9 @@ public function assertTaskCreated(Closure $closure): void
9191

9292
Assert::assertTrue($count > 0, 'Task was not created.');
9393
}
94+
95+
public function assertCreatedTaskCount(int $count): void
96+
{
97+
Assert::assertCount($count, $this->createdTasks);
98+
}
9499
}

src/CloudTasksConnector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ public function connect(array $config)
2323
};
2424
}
2525

26-
return new CloudTasksQueue($config, app(CloudTasksClient::class));
26+
return new CloudTasksQueue($config, app(CloudTasksClient::class), $config['after_commit'] ?? null);
2727
}
2828
}

src/CloudTasksJob.php

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,21 @@
33
namespace Stackkit\LaravelGoogleCloudTasksQueue;
44

55
use Illuminate\Container\Container;
6-
use Illuminate\Queue\Jobs\Job as LaravelJob;
76
use Illuminate\Contracts\Queue\Job as JobContract;
7+
use Illuminate\Queue\Jobs\Job as LaravelJob;
8+
use Stackkit\LaravelGoogleCloudTasksQueue\Events\JobReleased;
9+
use Stackkit\LaravelGoogleCloudTasksQueue\Events\JobReleasedAfterException;
810
use function Safe\json_encode;
911

1012
class CloudTasksJob extends LaravelJob implements JobContract
1113
{
12-
private array $job;
13-
private ?int $attempts;
14+
/**
15+
* The Cloud Tasks raw job payload (request payload).
16+
*
17+
* @var array
18+
*/
19+
public array $job;
20+
1421
private ?int $maxTries;
1522
public ?int $retryUntil = null;
1623

@@ -24,9 +31,14 @@ public function __construct(array $job, CloudTasksQueue $cloudTasksQueue)
2431
$this->job = $job;
2532
$this->container = Container::getInstance();
2633
$this->cloudTasksQueue = $cloudTasksQueue;
27-
/** @var \stdClass $command */
28-
$command = unserialize($job['data']['command']);
29-
$this->queue = $command->queue;
34+
35+
$command = TaskHandler::getCommandProperties($job['data']['command']);
36+
$this->queue = $command['queue'] ?? config('queue.connections.' .config('queue.default') . '.queue');
37+
}
38+
39+
public function job()
40+
{
41+
return $this->job;
3042
}
3143

3244
public function getJobId(): string
@@ -46,12 +58,12 @@ public function getRawBody(): string
4658

4759
public function attempts(): ?int
4860
{
49-
return $this->attempts;
61+
return $this->job['internal']['attempts'];
5062
}
5163

5264
public function setAttempts(int $attempts): void
5365
{
54-
$this->attempts = $attempts;
66+
$this->job['internal']['attempts'] = $attempts;
5567
}
5668

5769
public function setMaxTries(int $maxTries): void
@@ -95,4 +107,28 @@ public function delete(): void
95107

96108
$this->cloudTasksQueue->delete($this);
97109
}
110+
111+
public function release($delay = 0)
112+
{
113+
parent::release();
114+
115+
$this->cloudTasksQueue->release($this, $delay);
116+
117+
$properties = TaskHandler::getCommandProperties($this->job['data']['command']);
118+
$connection = $properties['connection'] ?? config('queue.default');
119+
120+
// The package uses the JobReleasedAfterException provided by Laravel to grab
121+
// the payload of the released job in tests to easily run and test a released
122+
// job. Because the event is only accessible in Laravel 9.x, we create an
123+
// identical event to hook into for Laravel versions older than 9.x
124+
if (version_compare(app()->version(), '9.0.0', '<')) {
125+
if (data_get($this->job, 'internal.errored')) {
126+
app('events')->dispatch(new JobReleasedAfterException($connection, $this));
127+
}
128+
}
129+
130+
if (! data_get($this->job, 'internal.errored')) {
131+
app('events')->dispatch(new JobReleased($connection, $this, $delay));
132+
}
133+
}
98134
}

0 commit comments

Comments
 (0)