Browse Source

Revert session handling changes

imwald
Nuša Pukšič 1 month ago
parent
commit
1b5ba80718
  1. 2
      config/packages/framework.yaml
  2. 9
      config/services.yaml
  3. 119
      src/Session/GracefulSessionHandler.php

2
config/packages/framework.yaml

@ -5,7 +5,7 @@ framework: @@ -5,7 +5,7 @@ framework:
# Note that the session will be started ONLY if you read or write from it.
session:
handler_id: App\Session\GracefulSessionHandler
handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler
cookie_secure: auto
cookie_samesite: lax
cookie_lifetime: 2678400 # integer, lifetime in seconds, 0 means 'valid for the length of the browser session'

9
config/services.yaml

@ -60,15 +60,6 @@ services: @@ -60,15 +60,6 @@ services:
- auth:
- '%env(REDIS_PASSWORD)%'
# Native file session handler for fallback
Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler: ~
# Graceful session handler that falls back to files on Redis outage
App\Session\GracefulSessionHandler:
arguments:
- '@Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler'
- '@Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler'
- '@logger'
App\Provider\ArticleProvider:
tags:

119
src/Session/GracefulSessionHandler.php

@ -1,119 +0,0 @@ @@ -1,119 +0,0 @@
<?php
namespace App\Session;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\AbstractSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler;
/**
* A session handler that tries Redis first, but gracefully falls back to files
* if Redis is unavailable at runtime.
*/
class GracefulSessionHandler extends AbstractSessionHandler
{
private RedisSessionHandler $redisHandler;
private NativeFileSessionHandler $fileHandler;
private LoggerInterface $logger;
private bool $useRedis = true;
private bool $handlerOpened = false;
public function __construct(RedisSessionHandler $redisHandler, NativeFileSessionHandler $fileHandler, LoggerInterface $logger)
{
$this->redisHandler = $redisHandler;
$this->fileHandler = $fileHandler;
$this->logger = $logger;
}
protected function doRead(string $sessionId): string
{
if ($this->useRedis) {
try {
$this->handlerOpened = true;
return $this->redisHandler->read($sessionId);
} catch (\Throwable $e) {
$this->useRedis = false;
$this->logger->warning('Redis session read failed; falling back to files', ['e' => $e->getMessage()]);
}
}
$this->handlerOpened = true;
return $this->fileHandler->read($sessionId);
}
public function updateTimestamp(string $sessionId, string $data): bool
{
if ($this->useRedis) {
try {
return $this->redisHandler->updateTimestamp($sessionId, $data);
} catch (\Throwable $e) {
$this->useRedis = false;
$this->logger->warning('Redis session touch failed; falling back to files', ['e' => $e->getMessage()]);
}
}
// NativeFileSessionHandler doesn't support updateTimestamp, just return true
return true;
}
protected function doWrite(string $sessionId, string $data): bool
{
if ($this->useRedis) {
try {
return $this->redisHandler->write($sessionId, $data);
} catch (\Throwable $e) {
$this->useRedis = false;
$this->logger->warning('Redis session write failed; falling back to files', ['e' => $e->getMessage()]);
}
}
return $this->fileHandler->write($sessionId, $data);
}
protected function doDestroy(string $sessionId): bool
{
if ($this->useRedis) {
try {
return $this->redisHandler->destroy($sessionId);
} catch (\Throwable $e) {
$this->useRedis = false;
$this->logger->warning('Redis session destroy failed; falling back to files', ['e' => $e->getMessage()]);
}
}
return $this->fileHandler->destroy($sessionId);
}
public function close(): bool
{
if (!$this->handlerOpened) {
return true;
}
try {
if ($this->useRedis) {
return $this->redisHandler->close();
} else {
return $this->fileHandler->close();
}
} catch (\Throwable $e) {
$this->logger->warning('Session close error', ['e' => $e->getMessage()]);
return false;
} finally {
$this->handlerOpened = false;
}
}
public function gc(int $max_lifetime): int|false
{
if ($this->useRedis) {
try {
return $this->redisHandler->gc($max_lifetime);
} catch (\Throwable $e) {
$this->useRedis = false;
$this->logger->warning('Redis session gc failed; falling back to files', ['e' => $e->getMessage()]);
}
}
return $this->fileHandler->gc($max_lifetime);
}
}
Loading…
Cancel
Save