fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled

- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
2025-11-09 14:46:15 +01:00
parent 85c369e846
commit 36ef2a1e2c
1366 changed files with 104925 additions and 28719 deletions

View File

@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace App\Framework\ExceptionHandling\Correlation;
/**
* Exception Correlation
*
* Immutable value object representing correlation between exceptions.
*/
final readonly class ExceptionCorrelation
{
/**
* @param string $correlationKey Correlation key (Request-ID, Session-ID, etc.)
* @param array<string> $exceptionIds Related exception IDs
* @param string|null $rootCauseId Root cause exception ID
*/
public function __construct(
public string $correlationKey,
public array $exceptionIds = [],
public ?string $rootCauseId = null
) {
}
/**
* Convert to array for serialization
*
* @return array<string, mixed>
*/
public function toArray(): array
{
return [
'correlation_key' => $this->correlationKey,
'exception_ids' => $this->exceptionIds,
'root_cause_id' => $this->rootCauseId,
];
}
}

View File

@@ -0,0 +1,131 @@
<?php
declare(strict_types=1);
namespace App\Framework\ExceptionHandling\Correlation;
use App\Framework\Cache\Cache;
use App\Framework\Cache\CacheItem;
use App\Framework\Cache\CacheKey;
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\ExceptionHandling\Context\ExceptionContextData;
use Throwable;
/**
* Exception Correlation Engine
*
* Correlates related exceptions for root cause analysis.
*/
final readonly class ExceptionCorrelationEngine
{
private const string CACHE_PREFIX = 'exception_correlation:';
private const int CACHE_TTL = 3600; // 1 hour
public function __construct(
private Cache $cache
) {
}
/**
* Correlate exception with related exceptions
*
* @param Throwable $exception Exception to correlate
* @param ExceptionContextData|null $context Optional context
* @return ExceptionCorrelation Correlation data
*/
public function correlate(Throwable $exception, ?ExceptionContextData $context = null): ExceptionCorrelation
{
$correlationKey = $this->extractCorrelationKey($context);
if ($correlationKey === null) {
return new ExceptionCorrelation(correlationKey: 'unknown');
}
$exceptionId = spl_object_id($exception);
$cacheKey = CacheKey::fromString(self::CACHE_PREFIX . $correlationKey);
// Get existing correlation
$existing = $this->getCorrelation($cacheKey);
$exceptionIds = $existing->exceptionIds;
$exceptionIds[] = (string) $exceptionId;
// First exception in correlation is root cause
$rootCauseId = $existing->rootCauseId ?? (string) $exceptionId;
$correlation = new ExceptionCorrelation(
correlationKey: $correlationKey,
exceptionIds: array_unique($exceptionIds),
rootCauseId: $rootCauseId
);
// Store correlation
$this->storeCorrelation($cacheKey, $correlation);
return $correlation;
}
/**
* Extract correlation key from context
*/
private function extractCorrelationKey(?ExceptionContextData $context): ?string
{
if ($context === null) {
return null;
}
// Prefer Request-ID, then Session-ID, then User-ID
if ($context->requestId !== null) {
$requestId = is_string($context->requestId) ? $context->requestId : $context->requestId->toString();
return 'request:' . $requestId;
}
if ($context->sessionId !== null) {
$sessionId = is_string($context->sessionId) ? $context->sessionId : $context->sessionId->toString();
return 'session:' . $sessionId;
}
if ($context->userId !== null) {
return 'user:' . $context->userId;
}
return null;
}
/**
* Get correlation from cache
*/
private function getCorrelation(CacheKey $cacheKey): ExceptionCorrelation
{
$result = $this->cache->get($cacheKey);
$item = $result->getFirstHit();
if ($item === null) {
return new ExceptionCorrelation(correlationKey: '');
}
$value = $item->value;
if (is_array($value)) {
return new ExceptionCorrelation(
correlationKey: $value['correlation_key'] ?? '',
exceptionIds: $value['exception_ids'] ?? [],
rootCauseId: $value['root_cause_id'] ?? null
);
}
return new ExceptionCorrelation(correlationKey: '');
}
/**
* Store correlation in cache
*/
private function storeCorrelation(CacheKey $cacheKey, ExceptionCorrelation $correlation): void
{
$cacheItem = CacheItem::fromKey(
$cacheKey,
$correlation->toArray(),
Duration::fromSeconds(self::CACHE_TTL)
);
$this->cache->set($cacheItem);
}
}