Hello,
I have a Laravel + Inertia application that uses a serverless database which shuts down if a database query is not received within one hour. Once shut down, it takes around 30 seconds to wake up. I admit this is awful, but I proposed multiple options to the client and they chose this with full knowledge.
By default, Laravel stores sessions in the database, so when someone visits the home page while the database is shut down it shows a blank screen with no UI until the database wakes up and handles the user session store query. For my requirements, session data must be encrypted, so we use the database driver for sessions.
I believe I have a solution, but I wanted to see if others here have faced a similar problem and think this solution (below) is sufficient or if additional measures are needed.
I believe what would work is to create a custom StartSession middleware like so which asynchronously queries the database if the user is not logged in, which will start up the database if it is shut down. Because we use SSO for logins, the log in process is not immediate, so this may trigger the start up soon enough for a user to not notice it much.
<?php
namespace App\Http\Middleware;
use Illuminate\Session\Middleware\StartSession as Middleware;
class StartSession extends Middleware
{
public function handle($request, \Closure $next)
{
if (!auth()->check()) {
defer(function () {
DB::select('SELECT 1');
});
$request->setLaravelSession(app('session')->driver('array'));
return $next($request);
}
return parent::handle($request, $next);
}
}
And register it in bootstrap/app.php:
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Inertia\Inertia;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
\App\Http\Middleware\HandleInertiaRequests::class,
\Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
], replace: [
\Illuminate\Session\Middleware\StartSession::class => \App\Http\Middleware\StartSession::class,
]);
})->create();
It's possible that I need to use encrypted file sessions for the session driver, which will allow the UI to not be blocked just for session queries to a shut-down database, as long as the files are deleted by Laravel automatically and don't just accumulate.