Skip to content

Commit 34b1803

Browse files
committed
Add Larastan and fix its issues
1 parent fba7079 commit 34b1803

19 files changed

+398
-198
lines changed

composer.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
"require": {
1111
"ext-json": "*",
1212
"phpseclib/phpseclib": "~2.0",
13-
"google/cloud-tasks": "^1.10"
13+
"google/cloud-tasks": "^1.10",
14+
"thecodingmachine/safe": "^2.1"
1415
},
1516
"require-dev": {
16-
"orchestra/testbench": "^4.0 || ^5.0 || ^6.0 || ^7.0"
17+
"orchestra/testbench": "^4.0 || ^5.0 || ^6.0 || ^7.0",
18+
"nunomaduro/larastan": "^1.0 || ^2.0",
19+
"thecodingmachine/phpstan-safe-rule": "^1.2"
1720
},
1821
"autoload": {
1922
"psr-4": {
@@ -22,7 +25,8 @@
2225
},
2326
"autoload-dev": {
2427
"psr-4": {
25-
"Tests\\": "tests/"
28+
"Tests\\": "tests/",
29+
"Factories\\": "factories/"
2630
}
2731
},
2832
"extra": {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Factories;
6+
7+
use Illuminate\Database\Eloquent\Factories\Factory;
8+
use Illuminate\Support\Str;
9+
use Stackkit\LaravelGoogleCloudTasksQueue\StackkitCloudTask;
10+
11+
class StackkitCloudTaskFactory extends Factory
12+
{
13+
protected $model = StackkitCloudTask::class;
14+
15+
public function definition()
16+
{
17+
return [
18+
'status' => 'pending',
19+
'queue' => 'barbequeue',
20+
'task_uuid' => (string) Str::uuid(),
21+
'name' => 'SimpleJob',
22+
'metadata' => '{}',
23+
'payload' => '{}',
24+
];
25+
}
26+
}

phpstan.neon

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
includes:
2+
- ./vendor/nunomaduro/larastan/extension.neon
3+
- ./vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon
4+
parameters:
5+
paths:
6+
- src
7+
level: 9
8+
checkMissingIterableValueType: false
9+
ignoreErrors:
10+
- '/Cannot call method when\(\) on mixed/'

src/Authenticate.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22

33
namespace Stackkit\LaravelGoogleCloudTasksQueue;
44

5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Symfony\Component\HttpFoundation\Response;
8+
59
class Authenticate
610
{
7-
public function handle($request, $next)
11+
/**
12+
* @return Response|never
13+
*/
14+
public function handle(Request $request, Closure $next)
815
{
916
return CloudTasks::check($request) ? $next($request) : abort(403);
1017
}
11-
}
18+
}

src/CloudTasks.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Closure;
66

7-
class CloudTasks
7+
final class CloudTasks
88
{
99
/**
1010
* The callback that should be used to authenticate Cloud Tasks users.
@@ -34,8 +34,6 @@ public static function auth(Closure $callback)
3434
*/
3535
public static function check($request)
3636
{
37-
return (static::$authUsing ?: function () {
38-
return app()->environment('local');
39-
})($request);
37+
return (static::$authUsing)($request);
4038
}
41-
}
39+
}

src/CloudTasksApiConcrete.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
namespace Stackkit\LaravelGoogleCloudTasksQueue;
66

7+
use Exception;
78
use Google\Cloud\Tasks\V2\Attempt;
89
use Google\Cloud\Tasks\V2\CloudTasksClient;
910
use Google\Cloud\Tasks\V2\RetryConfig;
1011
use Google\Cloud\Tasks\V2\Task;
12+
use Google\Protobuf\Duration;
13+
use Google\Protobuf\Timestamp;
1114

1215
class CloudTasksApiConcrete implements CloudTasksApiContract
1316
{
@@ -23,7 +26,13 @@ public function __construct(CloudTasksClient $client)
2326

2427
public function getRetryConfig(string $queueName): RetryConfig
2528
{
26-
return $this->client->getQueue($queueName)->getRetryConfig();
29+
$retryConfig = $this->client->getQueue($queueName)->getRetryConfig();
30+
31+
if (! $retryConfig instanceof RetryConfig) {
32+
throw new Exception('Queue does not have a retry config.');
33+
}
34+
35+
return $retryConfig;
2736
}
2837

2938
public function createTask(string $queueName, Task $task): Task
@@ -41,7 +50,6 @@ public function getTask(string $taskName): Task
4150
return $this->client->getTask($taskName);
4251
}
4352

44-
4553
public function getRetryUntilTimestamp(string $taskName): ?int
4654
{
4755
$task = $this->getTask($taskName);
@@ -56,13 +64,16 @@ public function getRetryUntilTimestamp(string $taskName): ?int
5664

5765
$retryConfig = $this->getRetryConfig($queueName);
5866

59-
if (! $retryConfig->hasMaxRetryDuration()) {
67+
$maxRetryDuration = $retryConfig->getMaxRetryDuration();
68+
$dispatchTime = $attempt->getDispatchTime();
69+
70+
if (! $maxRetryDuration instanceof Duration || ! $dispatchTime instanceof Timestamp) {
6071
return null;
6172
}
6273

63-
$maxDurationInSeconds = $retryConfig->getMaxRetryDuration()->getSeconds();
74+
$maxDurationInSeconds = (int) $maxRetryDuration->getSeconds();
6475

65-
$firstAttemptTimestamp = $attempt->getDispatchTime()->toDateTime()->getTimestamp();
76+
$firstAttemptTimestamp = $dispatchTime->toDateTime()->getTimestamp();
6677

6778
return $firstAttemptTimestamp + $maxDurationInSeconds;
6879
}

src/CloudTasksApiController.php

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
use Exception;
66
use Illuminate\Database\Eloquent\Builder;
77
use Illuminate\Support\Carbon;
8+
use Illuminate\Support\Collection;
89
use Illuminate\Support\Facades\DB;
10+
use Stackkit\LaravelGoogleCloudTasksQueue\Entities\StatRow;
911
use const STR_PAD_LEFT;
1012

1113
class CloudTasksApiController
1214
{
13-
public function dashboard()
15+
public function dashboard(): array
1416
{
1517
$dbDriver = config('database.connections.' . config('database.default') . '.driver');
1618

@@ -29,6 +31,9 @@ public function dashboard()
2931
],
3032
][$dbDriver];
3133

34+
/**
35+
* @var array<StatRow> $stats
36+
*/
3237
$stats = DB::table((new StackkitCloudTask())->getTable())
3338
->where('created_at', '>=', now()->utc()->startOfDay())
3439
->select(
@@ -52,6 +57,7 @@ public function dashboard()
5257
]
5358
)
5459
->get()
60+
->map(fn($row) => StatRow::createFromObject($row))
5561
->toArray();
5662

5763
$response = [
@@ -98,6 +104,9 @@ public function dashboard()
98104
return $response;
99105
}
100106

107+
/**
108+
* @return Collection<int, StackkitCloudTask>
109+
*/
101110
public function tasks()
102111
{
103112
Carbon::setTestNowAndTimezone(now()->utc());
@@ -112,12 +121,12 @@ public function tasks()
112121
[$hour, $minute] = explode(':', request('time'));
113122

114123
return $builder
115-
->where('created_at', '>=', now()->setTime($hour, $minute, 0))
116-
->where('created_at', '<=', now()->setTime($hour, $minute, 59));
124+
->where('created_at', '>=', now()->setTime((int) $hour, (int) $minute, 0))
125+
->where('created_at', '<=', now()->setTime((int) $hour, (int) $minute, 59));
117126
})
118127
->when(request('hour'), function (Builder $builder, $hour) {
119-
return $builder->where('created_at', '>=', now()->setTime($hour, 0, 0))
120-
->where('created_at', '<=', now()->setTime($hour, 59, 59));
128+
return $builder->where('created_at', '>=', now()->setTime((int) $hour, 0, 0))
129+
->where('created_at', '<=', now()->setTime((int) $hour, 59, 59));
121130
})
122131
->when(request('queue'), function (Builder $builder, $queue) {
123132
return $builder->where('queue', $queue);
@@ -130,26 +139,23 @@ public function tasks()
130139

131140
$maxId = $tasks->max('id');
132141

133-
return $tasks->map(function (StackkitCloudTask $task) use ($tasks, $maxId)
142+
return $tasks->map(function (StackkitCloudTask $task) use ($maxId)
134143
{
135-
return [
136-
'uuid' => $task->task_uuid,
137-
'id' => str_pad($task->id, strlen($maxId), 0, STR_PAD_LEFT),
138-
'name' => $task->name,
139-
'status' => $task->status,
140-
'attempts' => $task->getNumberOfAttempts(),
141-
'created' => $task->created_at->diffForHumans(),
142-
'queue' => $task->queue,
143-
];
144-
});
144+
return [
145+
'uuid' => $task->task_uuid,
146+
'id' => str_pad((string) $task->id, strlen($maxId), '0', STR_PAD_LEFT),
147+
'name' => $task->name,
148+
'status' => $task->status,
149+
'attempts' => $task->getNumberOfAttempts(),
150+
'created' => $task->created_at ? $task->created_at->diffForHumans() : null,
151+
'queue' => $task->queue,
152+
];
153+
});
145154
}
146155

147-
public function task($uuid)
156+
public function task(string $uuid): array
148157
{
149-
/**
150-
* @var StackkitCloudTask $task
151-
*/
152-
$task = StackkitCloudTask::whereTaskUuid($uuid)->firstOrFail();
158+
$task = StackkitCloudTask::findByUuid($uuid);
153159

154160
return [
155161
'id' => $task->id,
@@ -160,4 +166,4 @@ public function task($uuid)
160166
'exception' => $task->getMetadata()['exception'] ?? null,
161167
];
162168
}
163-
}
169+
}

src/CloudTasksJob.php

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,34 @@
22

33
namespace Stackkit\LaravelGoogleCloudTasksQueue;
44

5-
use Google\Cloud\Tasks\V2\CloudTasksClient;
65
use Illuminate\Container\Container;
76
use Illuminate\Queue\Jobs\Job as LaravelJob;
87
use Illuminate\Contracts\Queue\Job as JobContract;
8+
use function Safe\json_encode;
99

1010
class CloudTasksJob extends LaravelJob implements JobContract
1111
{
12-
private $job;
13-
private $attempts;
14-
private $maxTries;
15-
public $retryUntil = null;
12+
private array $job;
13+
private ?int $attempts;
14+
private ?int $maxTries;
15+
public ?int $retryUntil = null;
1616

1717
/**
1818
* @var CloudTasksQueue
1919
*/
2020
public $cloudTasksQueue;
2121

22-
public function __construct($job, CloudTasksQueue $cloudTasksQueue)
22+
public function __construct(array $job, CloudTasksQueue $cloudTasksQueue)
2323
{
2424
$this->job = $job;
2525
$this->container = Container::getInstance();
2626
$this->cloudTasksQueue = $cloudTasksQueue;
27+
/** @var \stdClass $command */
2728
$command = unserialize($job['data']['command']);
2829
$this->queue = $command->queue;
2930
}
3031

31-
public function getJobId()
32+
public function getJobId(): string
3233
{
3334
return $this->job['uuid'];
3435
}
@@ -38,64 +39,64 @@ public function uuid(): string
3839
return $this->job['uuid'];
3940
}
4041

41-
public function getRawBody()
42+
public function getRawBody(): string
4243
{
4344
return json_encode($this->job);
4445
}
4546

46-
public function attempts()
47+
public function attempts(): ?int
4748
{
4849
return $this->attempts;
4950
}
5051

51-
public function setAttempts($attempts)
52+
public function setAttempts(int $attempts): void
5253
{
5354
$this->attempts = $attempts;
5455
}
5556

56-
public function setMaxTries($maxTries)
57+
public function setMaxTries(int $maxTries): void
5758
{
58-
if ((int) $maxTries === -1) {
59+
if ($maxTries === -1) {
5960
$maxTries = 0;
6061
}
6162

6263
$this->maxTries = $maxTries;
6364
}
6465

65-
public function maxTries()
66+
public function maxTries(): ?int
6667
{
6768
return $this->maxTries;
6869
}
6970

70-
public function setQueue($queue)
71+
public function setQueue(string $queue): void
7172
{
7273
$this->queue = $queue;
7374
}
7475

75-
public function setRetryUntil($retryUntil)
76+
public function setRetryUntil(?int $retryUntil): void
7677
{
7778
$this->retryUntil = $retryUntil;
7879
}
7980

80-
public function retryUntil()
81+
public function retryUntil(): ?int
8182
{
8283
return $this->retryUntil;
8384
}
8485

8586
// timeoutAt was renamed to retryUntil in 8.x but we still support this.
86-
public function timeoutAt()
87+
public function timeoutAt(): ?int
8788
{
8889
return $this->retryUntil;
8990
}
9091

91-
public function delete()
92+
public function delete(): void
9293
{
9394
parent::delete();
9495

9596
$this->cloudTasksQueue->delete($this);
9697
}
9798

98-
public function fire()
99+
public function fire(): void
99100
{
100101
$this->attempts++;
101102

0 commit comments

Comments
 (0)