Skip to content

Commit

Permalink
fix: stats endpoint error when fetching failed job count (#4)
Browse files Browse the repository at this point in the history
* remove trycatch

* create test to suit expected outcome

* Apply fixes from StyleCI

* remove result cache

* enable tests

* eod checkin

* Apply fixes from StyleCI

* test passing locally

* Apply fixes from StyleCI

* php stan

* test queue is marked as running

* Apply fixes from StyleCI

---------

Co-authored-by: StyleCI Bot <[email protected]>
  • Loading branch information
imorland and StyleCIBot committed Nov 28, 2023
1 parent 74e197f commit 61bf2a7
Show file tree
Hide file tree
Showing 14 changed files with 258 additions and 75 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
run:
uses: flarum/framework/.github/workflows/[email protected]
with:
enable_backend_testing: false
enable_backend_testing: true
enable_phpstan: true

backend_directory: .
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
js/node_modules
vendor/
composer.lock
.phpunit.result.cache
26 changes: 22 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
},
"flarum-cli": {
"modules": {
"githubActions": true
"githubActions": true,
"backendTesting": true
}
}
},
Expand All @@ -50,13 +51,30 @@
}
},
"require-dev": {
"flarum/phpstan": "*"
"flarum/phpstan": "*",
"flarum/testing": "^1.0.0"
},
"scripts": {
"analyse:phpstan": "phpstan analyse",
"clear-cache:phpstan": "phpstan clear-result-cache"
"clear-cache:phpstan": "phpstan clear-result-cache",
"test": [
"@test:unit",
"@test:integration"
],
"test:unit": "phpunit -c tests/phpunit.unit.xml",
"test:integration": "phpunit -c tests/phpunit.integration.xml",
"test:setup": "@php tests/integration/setup.php"
},
"scripts-descriptions": {
"analyse:phpstan": "Run static analysis"
"analyse:phpstan": "Run static analysis",
"test": "Runs all tests.",
"test:unit": "Runs all unit tests.",
"test:integration": "Runs all integration tests.",
"test:setup": "Sets up a database for use with integration tests. Execute this only once."
},
"autoload-dev": {
"psr-4": {
"Blomstra\\DatabaseQueue\\Tests\\": "tests/"
}
}
}
7 changes: 3 additions & 4 deletions extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
use Illuminate\Console\Scheduling\Event;

return [
new DatabaseQueue(),

(new Extend\Frontend('admin'))
->js(__DIR__.'/js/dist/admin.js')
->css(__DIR__.'/resources/less/admin.less'),

new Extend\Locales(__DIR__.'/resources/locale'),

(new Extend\ServiceProvider())
->register(Provider\DatabaseQueueProvider::class),

(new Extend\Routes('api'))
->get('/database-queue/stats', 'database.queue.stats', Api\Controller\ShowQueueStatsController::class),

Expand All @@ -33,6 +34,4 @@
$e->everyMinute();
}),

(new Extend\ServiceProvider())
->register(Provider\DatabaseQueueProvider::class),
];
24 changes: 6 additions & 18 deletions src/Api/Controller/ShowQueueStatsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Illuminate\Contracts\Queue\Queue;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Queue\DatabaseQueue;
use Illuminate\Queue\Failed\FailedJobProviderInterface;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
Expand All @@ -30,20 +31,18 @@ class ShowQueueStatsController implements RequestHandlerInterface
*/
protected $queue;

/**
* @var \Illuminate\Queue\Failed\DatabaseUuidFailedJobProvider
*/
protected $failer;

/**
* @var SettingsRepositoryInterface
*/
protected $settings;

public function __construct(Queue $queue, SettingsRepositoryInterface $settings)
protected $failer;

public function __construct(Queue $queue, SettingsRepositoryInterface $settings, FailedJobProviderInterface $failer)
{
$this->queue = $queue;
$this->settings = $settings;
$this->failer = $failer;
}

public function handle(ServerRequestInterface $request): ResponseInterface
Expand All @@ -52,28 +51,17 @@ public function handle(ServerRequestInterface $request): ResponseInterface
throw new ModelNotFoundException();
}

$this->failer = resolve('queue.failer');

/** @var DatabaseQueue $queue */
$queue = $this->queue;

return new JsonResponse([
'queue' => $queue->getQueue(null),
'status' => $this->isStarted() ? 'running' : 'inactive',
'pendingJobs' => $queue->size(),
'failedJobs' => $this->getFailedJobCount(),
'failedJobs' => count($this->failer->all()),
]);
}

protected function getFailedJobCount(): int
{
try {
return count($this->failer->all());
} catch (\Exception $e) {
return 0;
}
}

protected function isStarted(): bool
{
$dbValue = $this->settings->get('database_queue.working');
Expand Down
48 changes: 0 additions & 48 deletions src/DatabaseQueue.php

This file was deleted.

30 changes: 30 additions & 0 deletions src/Provider/DatabaseQueueProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,42 @@
namespace Blomstra\DatabaseQueue\Provider;

use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\Config;
use Flarum\Queue\Console\WorkCommand;
use Illuminate\Contracts\Queue\Queue;
use Illuminate\Queue\DatabaseQueue;
use Illuminate\Queue\Failed\FailedJobProviderInterface;

class DatabaseQueueProvider extends AbstractServiceProvider
{
public function register()
{
$this->container->extend('flarum.queue.connection', function (Queue $queue) {
$queue = new DatabaseQueue(
$this->container->make('db.connection'),
'queue_jobs'
);

/** @phpstan-ignore-next-line */
$queue->setContainer($this->container);

return $queue;
});

$this->container->extend('queue.failer', function (FailedJobProviderInterface $failer) {
/** @var Config $config */
$config = $this->container->make(Config::class);

return new DatabaseUuidFailedJobProvider(
$this->container->make('db'),
$config->offsetGet('database.database'),
'queue_failed_jobs',
$this->container->make('flarum.db')
);
});

$this->container->alias('queue.failer', FailedJobProviderInterface::class);

$this->container->extend('flarum.console.commands', function (array $commands) {
$key = array_search(WorkCommand::class, $commands);

Expand Down
38 changes: 38 additions & 0 deletions src/Provider/DatabaseUuidFailedJobProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/*
* This file is part of blomstra/database-queue
*
* Copyright (c) 2023 Blomstra Ltd.
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*
*/

namespace Blomstra\DatabaseQueue\Provider;

use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\ConnectionResolverInterface;

class DatabaseUuidFailedJobProvider extends \Illuminate\Queue\Failed\DatabaseUuidFailedJobProvider
{
protected $connection;

public function __construct(ConnectionResolverInterface $resolver, $database, $table, ConnectionInterface $connection)
{
parent::__construct($resolver, $database, $table);

$this->connection = $connection;
}

/**
* Get a new query builder instance for the table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function getTable()
{
return $this->connection->table($this->table);
}
}
Empty file added tests/fixtures/.gitkeep
Empty file.
86 changes: 86 additions & 0 deletions tests/integration/api/StatsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

/*
* This file is part of blomstra/database-queue
*
* Copyright (c) 2023 Blomstra Ltd.
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*
*/

namespace Blomstra\DatabaseQueue\Tests\integration\api;

use Flarum\Testing\integration\ConsoleTestCase;

class StatsTest extends ConsoleTestCase
{
public function setUp(): void
{
$this->extension('blomstra-database-queue');
}

/**
* @test
*/
public function non_admin_cannot_access_stats()
{
$response = $this->send($this->request(
'GET',
'/api/database-queue/stats'
));

$this->assertEquals(404, $response->getStatusCode());
}

/**
* @test
*/
public function admin_can_access_stats()
{
$response = $this->send($this->request(
'GET',
'/api/database-queue/stats',
[
'authenticatedAs' => 1,
]
));

$this->assertEquals(200, $response->getStatusCode());

$body = json_decode($response->getBody(), true);

$this->assertEquals('default', $body['queue']);
$this->assertEquals('inactive', $body['status']);
$this->assertEquals(0, $body['pendingJobs']);
$this->assertEquals(0, $body['failedJobs']);
}

/**
* @test
*/
public function admin_can_access_stats_with_queue()
{
$commandOutput = $this->runCommand(['command' => 'queue:work', '--stop-when-empty' => true]);

$this->assertEmpty($commandOutput);

$response = $this->send($this->request(
'GET',
'/api/database-queue/stats',
[
'authenticatedAs' => 1,
]
));

$this->assertEquals(200, $response->getStatusCode());

$body = json_decode($response->getBody(), true);

$this->assertEquals('default', $body['queue']);
$this->assertEquals('running', $body['status']);
$this->assertEquals(0, $body['pendingJobs']);
$this->assertEquals(0, $body['failedJobs']);
}
}
19 changes: 19 additions & 0 deletions tests/integration/setup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/*
* This file is part of blomstra/database-queue
*
* Copyright (c) 2023 Blomstra Ltd.
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*
*/

use Flarum\Testing\integration\Setup\SetupScript;

require __DIR__.'/../../vendor/autoload.php';

$setup = new SetupScript();

$setup->run();
Loading

0 comments on commit 61bf2a7

Please sign in to comment.