mirror of
https://github.com/flarum/framework.git
synced 2025-02-18 03:22:45 +08:00
Move garbage collection into middleware
This prevents garbage collection to randomly break the installer: before installation, the models that are being accessed have no database connection. Now, the middleware is only mounted into the forum's middleware stack. I want API requests to have stable performance, and the forum middleware stack is only mounted when Flarum is installed.
This commit is contained in:
parent
c8a1a5fcfa
commit
56231d61be
|
@ -17,6 +17,7 @@ use Flarum\Extension\Event\Disabled;
|
||||||
use Flarum\Extension\Event\Enabled;
|
use Flarum\Extension\Event\Enabled;
|
||||||
use Flarum\Foundation\AbstractServiceProvider;
|
use Flarum\Foundation\AbstractServiceProvider;
|
||||||
use Flarum\Http\Middleware\AuthenticateWithSession;
|
use Flarum\Http\Middleware\AuthenticateWithSession;
|
||||||
|
use Flarum\Http\Middleware\CollectGarbage;
|
||||||
use Flarum\Http\Middleware\DispatchRoute;
|
use Flarum\Http\Middleware\DispatchRoute;
|
||||||
use Flarum\Http\Middleware\HandleErrors;
|
use Flarum\Http\Middleware\HandleErrors;
|
||||||
use Flarum\Http\Middleware\ParseJsonBody;
|
use Flarum\Http\Middleware\ParseJsonBody;
|
||||||
|
@ -54,6 +55,7 @@ class ForumServiceProvider extends AbstractServiceProvider
|
||||||
$pipe->pipe($app->make(HandleErrors::class, ['debug' => $debugMode]));
|
$pipe->pipe($app->make(HandleErrors::class, ['debug' => $debugMode]));
|
||||||
|
|
||||||
$pipe->pipe($app->make(ParseJsonBody::class));
|
$pipe->pipe($app->make(ParseJsonBody::class));
|
||||||
|
$pipe->pipe($app->make(CollectGarbage::class));
|
||||||
$pipe->pipe($app->make(StartSession::class));
|
$pipe->pipe($app->make(StartSession::class));
|
||||||
$pipe->pipe($app->make(RememberFromCookie::class));
|
$pipe->pipe($app->make(RememberFromCookie::class));
|
||||||
$pipe->pipe($app->make(AuthenticateWithSession::class));
|
$pipe->pipe($app->make(AuthenticateWithSession::class));
|
||||||
|
|
55
src/Http/Middleware/CollectGarbage.php
Normal file
55
src/Http/Middleware/CollectGarbage.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\Middleware;
|
||||||
|
|
||||||
|
use Flarum\Http\AccessToken;
|
||||||
|
use Flarum\User\AuthToken;
|
||||||
|
use Flarum\User\EmailToken;
|
||||||
|
use Flarum\User\PasswordToken;
|
||||||
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
use Zend\Stratigility\MiddlewareInterface;
|
||||||
|
|
||||||
|
class CollectGarbage implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __invoke(Request $request, Response $response, callable $out = null)
|
||||||
|
{
|
||||||
|
$this->collectGarbageSometimes();
|
||||||
|
|
||||||
|
return $out ? $out($request, $response) : $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function collectGarbageSometimes()
|
||||||
|
{
|
||||||
|
// In order to save performance, we only execute this query
|
||||||
|
// from time to time (with 50% chance).
|
||||||
|
if (! $this->hit()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessToken::whereRaw('last_activity <= ? - lifetime', [time()])->delete();
|
||||||
|
|
||||||
|
$earliestToKeep = date('Y-m-d H:i:s', time() - 24 * 60 * 60);
|
||||||
|
|
||||||
|
EmailToken::where('created_at', '<=', $earliestToKeep)->delete();
|
||||||
|
PasswordToken::where('created_at', '<=', $earliestToKeep)->delete();
|
||||||
|
AuthToken::where('created_at', '<=', $earliestToKeep)->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function hit()
|
||||||
|
{
|
||||||
|
return mt_rand(1, 100) <= 2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,9 +18,6 @@ use Flarum\Http\Middleware\HandleErrors;
|
||||||
use Flarum\Http\Middleware\StartSession;
|
use Flarum\Http\Middleware\StartSession;
|
||||||
use Flarum\Install\InstallServiceProvider;
|
use Flarum\Install\InstallServiceProvider;
|
||||||
use Flarum\Update\UpdateServiceProvider;
|
use Flarum\Update\UpdateServiceProvider;
|
||||||
use Flarum\User\AuthToken;
|
|
||||||
use Flarum\User\EmailToken;
|
|
||||||
use Flarum\User\PasswordToken;
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Zend\Diactoros\Response\HtmlResponse;
|
use Zend\Diactoros\Response\HtmlResponse;
|
||||||
|
@ -67,9 +64,6 @@ class Server
|
||||||
*/
|
*/
|
||||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $out)
|
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $out)
|
||||||
{
|
{
|
||||||
// FIXME: Only call this when app is installed. Do this via middleware?
|
|
||||||
$this->collectGarbage();
|
|
||||||
|
|
||||||
$middleware = $this->getMiddleware($request->getUri()->getPath());
|
$middleware = $this->getMiddleware($request->getUri()->getPath());
|
||||||
|
|
||||||
return $middleware($request, $response, $out);
|
return $middleware($request, $response, $out);
|
||||||
|
@ -152,24 +146,6 @@ class Server
|
||||||
return $pipe;
|
return $pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function collectGarbage()
|
|
||||||
{
|
|
||||||
if ($this->hitsLottery()) {
|
|
||||||
AccessToken::whereRaw('last_activity <= ? - lifetime', [time()])->delete();
|
|
||||||
|
|
||||||
$earliestToKeep = date('Y-m-d H:i:s', time() - 24 * 60 * 60);
|
|
||||||
|
|
||||||
EmailToken::where('created_at', '<=', $earliestToKeep)->delete();
|
|
||||||
PasswordToken::where('created_at', '<=', $earliestToKeep)->delete();
|
|
||||||
AuthToken::where('created_at', '<=', $earliestToKeep)->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function hitsLottery()
|
|
||||||
{
|
|
||||||
return mt_rand(1, 100) <= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getErrorDir()
|
private function getErrorDir()
|
||||||
{
|
{
|
||||||
return __DIR__.'/../../error';
|
return __DIR__.'/../../error';
|
||||||
|
|
Loading…
Reference in New Issue
Block a user