diff --git a/routes/web.php b/routes/web.php index 2593026..e062686 100644 --- a/routes/web.php +++ b/routes/web.php @@ -14,6 +14,10 @@ use Illuminate\Support\Facades\Route; Route::prefix('api')->namespace('Api')->name('paket.api.')->group(function () { + Route::get('statuses') + ->uses('Statuses\CollectAction') + ->name('statuses.collect'); + Route::get('repositories') ->uses('Repositories\CollectAction') ->name('repositories.collect'); diff --git a/src/Http/Controllers/Api/Statuses/CollectAction.php b/src/Http/Controllers/Api/Statuses/CollectAction.php new file mode 100644 index 0000000..7f1b4ee --- /dev/null +++ b/src/Http/Controllers/Api/Statuses/CollectAction.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Cog\Laravel\Paket\Http\Controllers\Api\Statuses; + +use Cog\Laravel\Paket\Support\Queue\Events\QueueHasBeenPinged; +use Cog\Laravel\Paket\Support\Queue\Listeners\QueuePingListener; +use Illuminate\Contracts\Events\Dispatcher; +use Illuminate\Support\Facades\File; +use Laravel\Horizon\Contracts\MasterSupervisorRepository; +use Ramsey\Uuid\Uuid; + +final class CollectAction +{ + public function __invoke() + { + return [ + 'queue' => $this->resolveQueueStatus(), + ]; + } + + private function resolveQueueStatus(): array + { + $queueConnection = config('queue.default'); + + if ($queueConnection === 'sync') { + return [ + 'handler' => 'Illuminate', + 'connection' => $queueConnection, + 'status' => 'inactive', + ]; + } + + if (interface_exists(MasterSupervisorRepository::class)) { + $horizonQueueStatus = $this->resolveHorizonQueueStatus(); + if ($horizonQueueStatus !== 'inactive') { + return [ + 'handler' => 'Horizon', + 'connection' => $queueConnection, + 'status' => $horizonQueueStatus, + ]; + } + } + + return [ + 'handler' => 'Illuminate', + 'connection' => $queueConnection, + 'status' => $this->resolveIlluminateQueueStatus(), + ]; + } + + private function resolveHorizonQueueStatus(): string + { + if (!$masters = app(MasterSupervisorRepository::class)->all()) { + return 'inactive'; + } + + return collect($masters)->contains(function ($master) { + return $master->status === 'paused'; + }) ? 'paused' : 'running'; + } + + private function resolveIlluminateQueueStatus(): string + { + $uuid = Uuid::uuid4()->toString(); + + $dispatcher = app(Dispatcher::class); + $dispatcher->listen(QueueHasBeenPinged::class, QueuePingListener::class); + $dispatcher->dispatch(new QueueHasBeenPinged($uuid)); + sleep(2); + + $storedUuid = File::get(storage_path('paket/queue-ping.log')); + + return $uuid === $storedUuid ? 'running' : 'inactive'; + } +} diff --git a/src/Support/Queue/Events/QueueHasBeenPinged.php b/src/Support/Queue/Events/QueueHasBeenPinged.php new file mode 100644 index 0000000..1f88f3c --- /dev/null +++ b/src/Support/Queue/Events/QueueHasBeenPinged.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Cog\Laravel\Paket\Support\Queue\Events; + +final class QueueHasBeenPinged +{ + private $id; + + public function __construct(string $id) + { + $this->id = $id; + } + + public function getId(): string + { + return $this->id; + } +} diff --git a/src/Support/Queue/Listeners/QueuePingListener.php b/src/Support/Queue/Listeners/QueuePingListener.php new file mode 100644 index 0000000..aa8d46b --- /dev/null +++ b/src/Support/Queue/Listeners/QueuePingListener.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Cog\Laravel\Paket\Support\Queue\Listeners; + +use Cog\Laravel\Paket\Support\Queue\Events\QueueHasBeenPinged; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Support\Facades\File; + +final class QueuePingListener implements ShouldQueue +{ + public function handle(QueueHasBeenPinged $event): void + { + File::put(storage_path('paket/queue-ping.log'), $event->getId()); + } +}