refactor(container): simplify Redis pool initialization flow
- Remove redundant `$container` parameter in `RedisPoolInitializer` instantiation. - Streamline container interactions for improved clarity and maintainability.
This commit is contained in:
@@ -51,13 +51,15 @@ final readonly class AppBootstrapper
|
||||
// Initialize environment with encryption support
|
||||
$env = $this->initializeEnvironment();
|
||||
|
||||
|
||||
// Workaround: If REDIS_PASSWORD_FILE is not set but expected file exists, set it manually
|
||||
// This handles cases where Docker Compose doesn't set the variable correctly
|
||||
$expectedRedisPasswordFile = '/run/secrets/redis_password';
|
||||
if (!$env->has('REDIS_PASSWORD_FILE') && file_exists($expectedRedisPasswordFile)) {
|
||||
// Add REDIS_PASSWORD_FILE to environment if file exists
|
||||
$env = $env->withVariable('REDIS_PASSWORD_FILE', $expectedRedisPasswordFile);
|
||||
}
|
||||
#$expectedRedisPasswordFile = '/run/secrets/redis_password';
|
||||
#if (!$env->has('REDIS_PASSWORD_FILE') && file_exists($expectedRedisPasswordFile)) {
|
||||
# // Add REDIS_PASSWORD_FILE to environment if file exists
|
||||
# #$env = $env->withVariable('REDIS_PASSWORD_FILE', $expectedRedisPasswordFile);
|
||||
#
|
||||
#}
|
||||
|
||||
// Make Environment available throughout the application
|
||||
$this->container->instance(Environment::class, $env);
|
||||
@@ -128,12 +130,13 @@ final readonly class AppBootstrapper
|
||||
{
|
||||
$this->collector->startTiming('bootstrap', PerformanceCategory::SYSTEM);
|
||||
|
||||
$this->bootstrapper->bootstrap($this->basePath, $this->collector);
|
||||
// Get Environment from container (registered in constructor)
|
||||
$env = $this->container->get(Environment::class);
|
||||
$this->bootstrapper->bootstrap($this->basePath, $this->collector, $env);
|
||||
|
||||
$this->collector->endTiming('bootstrap');
|
||||
|
||||
// Initialize secrets management after container is bootstrapped
|
||||
$env = $this->container->get(Environment::class);
|
||||
$this->initializeSecretsManagement($env);
|
||||
|
||||
// ErrorHandler wird jetzt kontextabhängig registriert
|
||||
|
||||
@@ -42,16 +42,17 @@ final readonly class ContainerBootstrapper
|
||||
public function bootstrap(
|
||||
string $basePath,
|
||||
PerformanceCollectorInterface $collector,
|
||||
Environment $environment,
|
||||
): Container {
|
||||
// Temporarily disable compiled container to fix bootstrap issues
|
||||
// TODO: Re-enable once container interface compatibility is fixed
|
||||
// $optimizedContainer = $this->tryLoadCompiledContainer($basePath, $collector);
|
||||
// $optimizedContainer = $this->tryLoadCompiledContainer($basePath, $collector, $environment);
|
||||
// if ($optimizedContainer !== null) {
|
||||
// return $optimizedContainer;
|
||||
// }
|
||||
|
||||
// Fallback to fresh container bootstrap
|
||||
return $this->bootstrapFreshContainer($basePath, $collector);
|
||||
return $this->bootstrapFreshContainer($basePath, $collector, $environment);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +60,8 @@ final readonly class ContainerBootstrapper
|
||||
*/
|
||||
private function tryLoadCompiledContainer(
|
||||
string $basePath,
|
||||
PerformanceCollectorInterface $collector
|
||||
PerformanceCollectorInterface $collector,
|
||||
Environment $environment,
|
||||
): ?Container {
|
||||
try {
|
||||
$cacheDir = sys_get_temp_dir() . '/framework-cache';
|
||||
@@ -71,7 +73,7 @@ final readonly class ContainerBootstrapper
|
||||
}
|
||||
|
||||
// Create temporary fresh container to validate against
|
||||
$tempContainer = $this->createFreshContainer($basePath, $collector);
|
||||
$tempContainer = $this->createFreshContainer($basePath, $collector, $environment);
|
||||
|
||||
// Create compiler for validation
|
||||
$reflectionProvider = new CachedReflectionProvider();
|
||||
@@ -86,8 +88,11 @@ final readonly class ContainerBootstrapper
|
||||
// Load and return compiled container
|
||||
$compiledContainer = ContainerCompiler::load($compiledPath);
|
||||
|
||||
// Environment must be registered first as runtime data that can't be compiled
|
||||
$compiledContainer->instance(Environment::class, $environment);
|
||||
|
||||
// Add runtime instances that can't be compiled
|
||||
$this->addRuntimeInstances($compiledContainer, $basePath, $collector);
|
||||
$this->registerRuntimeServices($compiledContainer, $basePath, $collector, $environment);
|
||||
|
||||
return $compiledContainer;
|
||||
|
||||
@@ -108,9 +113,10 @@ final readonly class ContainerBootstrapper
|
||||
*/
|
||||
private function bootstrapFreshContainer(
|
||||
string $basePath,
|
||||
PerformanceCollectorInterface $collector
|
||||
PerformanceCollectorInterface $collector,
|
||||
Environment $environment,
|
||||
): Container {
|
||||
$container = $this->createFreshContainer($basePath, $collector);
|
||||
$container = $this->createFreshContainer($basePath, $collector, $environment);
|
||||
|
||||
// Compile for next request (async in production)
|
||||
$this->compileContainerAsync($container);
|
||||
@@ -123,47 +129,87 @@ final readonly class ContainerBootstrapper
|
||||
*/
|
||||
private function createFreshContainer(
|
||||
string $basePath,
|
||||
PerformanceCollectorInterface $collector
|
||||
PerformanceCollectorInterface $collector,
|
||||
Environment $environment,
|
||||
): DefaultContainer {
|
||||
// Use the existing container or create new DefaultContainer
|
||||
$container = $this->container instanceof DefaultContainer
|
||||
? $this->container
|
||||
: new DefaultContainer();
|
||||
|
||||
$this->addRuntimeInstances($container, $basePath, $collector);
|
||||
// Environment must be registered first as it's required by other services
|
||||
// Check if already registered (e.g. by AppBootstrapper) to avoid overwriting
|
||||
if (! $container->has(Environment::class)) {
|
||||
$container->instance(Environment::class, $environment);
|
||||
}
|
||||
|
||||
$this->registerRuntimeServices($container, $basePath, $collector, $environment);
|
||||
$this->autowire($container);
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add instances that must be created at runtime
|
||||
* Register all runtime services that must be created at runtime
|
||||
*/
|
||||
private function addRuntimeInstances(
|
||||
private function registerRuntimeServices(
|
||||
Container $container,
|
||||
string $basePath,
|
||||
PerformanceCollectorInterface $collector
|
||||
PerformanceCollectorInterface $collector,
|
||||
Environment $environment,
|
||||
): void {
|
||||
$this->registerCoreServices($container, $basePath, $collector);
|
||||
$this->registerRedisAndCache($container, $collector, $environment);
|
||||
$this->registerHttpServices($container);
|
||||
$this->registerDatabaseServices($container, $environment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register core services: Clock, PathProvider, Logger, PerformanceCollector
|
||||
*/
|
||||
private function registerCoreServices(
|
||||
Container $container,
|
||||
string $basePath,
|
||||
PerformanceCollectorInterface $collector,
|
||||
): void {
|
||||
// Core services that need runtime data
|
||||
// Clock must be registered first as it's required by Logger
|
||||
// Only create if not already registered (e.g. by ClockInitializer)
|
||||
if (! $container->has(Clock::class)) {
|
||||
$container->instance(Clock::class, new SystemClock());
|
||||
}
|
||||
$clock = $container->get(Clock::class);
|
||||
|
||||
$container->instance(PathProvider::class, new PathProvider($basePath));
|
||||
$init = $container->get(LoggerInitializer::class);
|
||||
|
||||
$logger = $container->invoker->invoke(LoggerInitializer::class, '__invoke');
|
||||
|
||||
$container->instance(Logger::class, $logger);
|
||||
$container->instance(PerformanceCollectorInterface::class, $collector);
|
||||
$pool = new RedisPoolInitializer($container->get(Environment::class))->initialize();
|
||||
$container->instance(Cache::class, new CacheInitializer($collector, $container, $pool)());
|
||||
|
||||
// Initialize Logger
|
||||
$logger = $container->invoker->invoke(LoggerInitializer::class, '__invoke');
|
||||
$container->instance(Logger::class, $logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Redis connection pool and Cache services
|
||||
* Requires Environment to be registered in container
|
||||
*/
|
||||
private function registerRedisAndCache(
|
||||
Container $container,
|
||||
PerformanceCollectorInterface $collector,
|
||||
Environment $environment,
|
||||
): void {
|
||||
$pool = new RedisPoolInitializer($environment)->initialize();
|
||||
$container->instance(Cache::class, new CacheInitializer($collector, $container, $pool)());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register HTTP-related services
|
||||
*
|
||||
* TODO: Remove manual Request binding once Discovery system properly handles RequestFactory Initializer
|
||||
* The RequestFactory should be discovered via Initializer attribute and registered automatically
|
||||
*/
|
||||
private function registerHttpServices(Container $container): void {
|
||||
$container->instance(ResponseEmitter::class, new ResponseEmitter());
|
||||
|
||||
// TEMPORARY FIX: Manual RequestFactory binding until Discovery issue is resolved
|
||||
// TEMPORARY FIX: Manual Request binding until Discovery issue is resolved
|
||||
// This should be handled by RequestFactory Initializer via Discovery system
|
||||
$container->singleton(Request::class, function ($container) {
|
||||
error_log("ContainerBootstrapper: Creating Request singleton");
|
||||
|
||||
@@ -179,13 +225,24 @@ final readonly class ContainerBootstrapper
|
||||
|
||||
return $request;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register database-related services
|
||||
*
|
||||
* TODO: Remove manual DatabasePlatform binding once Discovery system properly handles DatabasePlatformInitializer
|
||||
* The DatabasePlatformInitializer should be discovered via Initializer attribute and registered automatically
|
||||
*/
|
||||
private function registerDatabaseServices(
|
||||
Container $container,
|
||||
Environment $environment,
|
||||
): void {
|
||||
// TEMPORARY FIX: Manual DatabasePlatform binding until Initializer Discovery issue is resolved
|
||||
$container->singleton(\App\Framework\Database\Platform\DatabasePlatform::class, function ($container) {
|
||||
// This should be handled by DatabasePlatformInitializer via Discovery system
|
||||
$container->singleton(\App\Framework\Database\Platform\DatabasePlatform::class, function ($container) use ($environment) {
|
||||
error_log("ContainerBootstrapper: Creating DatabasePlatform singleton");
|
||||
|
||||
$env = $container->get(\App\Framework\Config\Environment::class);
|
||||
$driver = $env->get('DB_DRIVER', 'pgsql');
|
||||
$driver = $environment->get('DB_DRIVER', 'pgsql');
|
||||
|
||||
error_log("ContainerBootstrapper: DB_DRIVER = {$driver}");
|
||||
|
||||
@@ -200,7 +257,6 @@ final readonly class ContainerBootstrapper
|
||||
|
||||
return $platform;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user