-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Queue): Add ability to dispatch job in testable way
- Loading branch information
Showing
30 changed files
with
1,150 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Exceptions\Exceptions; | ||
|
||
use LogicException as BaseException; | ||
|
||
final class LogicException extends BaseException | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Actions; | ||
|
||
use LaraStrict\Queue\Contracts\DispatchChainJobsActionContract; | ||
use LaraStrict\Queue\Contracts\DispatchJobActionContract; | ||
|
||
class DispatchChainJobsAction implements DispatchChainJobsActionContract | ||
{ | ||
public function __construct( | ||
private readonly DispatchJobActionContract $dispatchJobAction | ||
) { | ||
} | ||
|
||
public function execute(array $jobs): bool | ||
{ | ||
if ($jobs === []) { | ||
return false; | ||
} | ||
|
||
if (count($jobs) === 1) { | ||
return $this->dispatchJobAction->execute(reset($jobs)); | ||
} | ||
|
||
$mainJob = array_shift($jobs); | ||
|
||
// After main job is done, chain our jobs | ||
$mainJob->chain($jobs); | ||
|
||
// Set the chain queue | ||
$mainJob->chainQueue = $mainJob->queue; | ||
|
||
// Dispatch chained job | ||
return $this->dispatchJobAction->execute($mainJob); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Actions; | ||
|
||
use LaraStrict\Queue\Contracts\DispatchJobActionContract; | ||
use LaraStrict\Queue\Jobs\Job; | ||
|
||
final class DispatchJobAction implements DispatchJobActionContract | ||
{ | ||
public function execute(Job $job): bool | ||
{ | ||
// Laravel requires PendingDispatch instance to be used for dispatching jobs with ShouldBeUnique :( | ||
dispatch($job); | ||
|
||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Actions; | ||
|
||
use Illuminate\Console\Command; | ||
use Illuminate\Contracts\Container\Container; | ||
use LaraStrict\Queue\Contracts\RunJobActionContract; | ||
use LaraStrict\Queue\Exceptions\MethodInJobIsNotDefinedException; | ||
use LaraStrict\Queue\Interfaces\UsesCommandInterface; | ||
use LaraStrict\Queue\Jobs\Job; | ||
|
||
class RunJobAction implements RunJobActionContract | ||
{ | ||
public function __construct( | ||
private readonly Container $container | ||
) { | ||
} | ||
|
||
public function execute(Job $job, ?Command $command = null, string $method = null): mixed | ||
{ | ||
if ($command !== null && $job instanceof UsesCommandInterface) { | ||
$job->setCommand($command); | ||
} | ||
|
||
$method ??= 'handle'; | ||
$call = [$job, $method]; | ||
|
||
if (is_callable($call) === false) { | ||
throw new MethodInJobIsNotDefinedException($method, $job::class); | ||
} | ||
|
||
return $this->container->call($call); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Actions; | ||
|
||
use Closure; | ||
use Illuminate\Console\Command; | ||
use LaraStrict\Queue\Contracts\DispatchJobActionContract; | ||
use LaraStrict\Queue\Contracts\RunJobActionContract; | ||
use LaraStrict\Queue\Contracts\RunOrQueueJobActionContract; | ||
use LaraStrict\Queue\Jobs\Job; | ||
|
||
class RunOrQueueJobAction implements RunOrQueueJobActionContract | ||
{ | ||
public function __construct( | ||
private readonly RunJobActionContract $runJobAction, | ||
private readonly DispatchJobActionContract $dispatchJobAction | ||
) { | ||
} | ||
|
||
/** | ||
* Allows to run or queue job based on the command option queue parameter or not providing a $command. | ||
* | ||
* @param Closure(Job):void|null $setupBeforeRun | ||
* @param bool|null $shouldQueue You can force to queue the job even if the command option queue is set. | ||
* | ||
* @return mixed If the job is queued, it returns null, otherwise it returns the result of the job execution. | ||
*/ | ||
public function execute( | ||
Job $job, | ||
?Command $command = null, | ||
?Closure $setupBeforeRun = null, | ||
?bool $shouldQueue = null, | ||
): mixed { | ||
if ($shouldQueue === true | ||
|| $shouldQueue === null && ($command === null || $command->option('queue') === true)) { | ||
$this->dispatchJobAction->execute($job); | ||
|
||
return null; | ||
} | ||
|
||
if ($setupBeforeRun !== null) { | ||
$setupBeforeRun($job); | ||
} | ||
|
||
return $this->runJobAction->execute(job: $job, command: $command); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Concerns; | ||
|
||
use Illuminate\Console\Command; | ||
|
||
trait UsesCommand | ||
{ | ||
private ?Command $command = null; | ||
|
||
public function setCommand(Command $command): void | ||
{ | ||
$this->command = $command; | ||
} | ||
|
||
public function getCommand(): ?Command | ||
{ | ||
return $this->command; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Contracts; | ||
|
||
use LaraStrict\Queue\Jobs\Job; | ||
|
||
interface DispatchChainJobsActionContract | ||
{ | ||
/** | ||
* Dispatches given chain of jobs (first job is used as main job and the rest are chained to it). | ||
* | ||
* If only one job is given, it will be dispatched directly. | ||
* | ||
* Ensures that the chainQueue is set to the main job's queue. | ||
* | ||
* @param Job[] $jobs | ||
* | ||
* @return bool True if the job was dispatched, false if the job was not dispatched. | ||
*/ | ||
public function execute(array $jobs): bool; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Contracts; | ||
|
||
use LaraStrict\Queue\Jobs\Job; | ||
|
||
interface DispatchJobActionContract | ||
{ | ||
/** | ||
* Dispatch a job to the queue. | ||
* - Wraps a dispatch() method. It is used to | ||
*/ | ||
public function execute(Job $job): bool; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Contracts; | ||
|
||
use Illuminate\Console\Command; | ||
use LaraStrict\Queue\Jobs\Job; | ||
|
||
interface RunJobActionContract | ||
{ | ||
/** | ||
* Runs the job using container->call() method. If the job is an instance of UsesCommandInterface, it will set the | ||
* command. that you can use for advanced output. | ||
* | ||
* @return mixed Returns the result of the job | ||
*/ | ||
public function execute(Job $job, ?Command $command = null): mixed; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Contracts; | ||
|
||
use Closure; | ||
use Illuminate\Console\Command; | ||
use LaraStrict\Queue\Jobs\Job; | ||
|
||
interface RunOrQueueJobActionContract | ||
{ | ||
/** | ||
* Allows to run or queue job based on the command option queue parameter or not providing a $command. | ||
* | ||
* @param Closure(Job):void|null $setupBeforeRun | ||
* @param bool|null $shouldQueue You can force to queue the job even if the command option queue is | ||
* set. | ||
* | ||
* @return mixed If the job is queued, it returns null, otherwise it returns the result of the job execution. | ||
*/ | ||
public function execute( | ||
Job $job, | ||
?Command $command = null, | ||
?Closure $setupBeforeRun = null, | ||
?bool $shouldQueue = null | ||
): mixed; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Exceptions; | ||
|
||
use RuntimeException; | ||
use Throwable; | ||
|
||
final class MethodInJobIsNotDefinedException extends RuntimeException | ||
{ | ||
/** | ||
* @param class-string $jobClass | ||
*/ | ||
public function __construct(string $method, string $jobClass, int $code = 0, ?Throwable $previous = null) | ||
{ | ||
parent::__construct(sprintf( | ||
'Given job <%s> does not contain desired method <%s>', | ||
$jobClass, | ||
$method | ||
), $code, $previous); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Interfaces; | ||
|
||
use Illuminate\Console\Command; | ||
|
||
/** | ||
* Implementations of UsesCommand trait | ||
* | ||
* @see \LaraStrict\Queue\Concerns\UsesCommand | ||
*/ | ||
interface UsesCommandInterface | ||
{ | ||
public function setCommand(Command $command): void; | ||
|
||
public function getCommand(): ?Command; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LaraStrict\Queue\Jobs; | ||
|
||
use Illuminate\Bus\Queueable; | ||
use Illuminate\Contracts\Queue\ShouldQueue; | ||
use Illuminate\Queue\InteractsWithQueue; | ||
|
||
abstract class Job implements ShouldQueue | ||
{ | ||
use Queueable; | ||
use InteractsWithQueue; | ||
|
||
public function __construct() | ||
{ | ||
// When queueing a job with schedule then the queue is not set by Laravel, this will | ||
// fix it. | ||
if ($this->queue === null) { | ||
$this->queue = 'default'; | ||
} | ||
} | ||
} |
Oops, something went wrong.