1.15.0
1.15.0
Eager singleton warm-up for coroutine runtimes
Compiler now writes singletons.json alongside the compiled scripts, and CompiledInjector::warmup() instantiates every listed singleton eagerly:
$injector = new CompiledInjector($scriptDir);
$injector->warmup(); // call once at worker startupIn coroutine runtimes (Swoole, OpenSwoole), lazy singleton initialization can race when construction yields, producing duplicate instances. Calling warmup() before concurrent request handling removes that window. Standard PHP-FPM workers process one request at a time, so no warm-up is required there. [#137] [#140]
Compile-time rejection of injection-point singletons
A singleton whose construction needs a caller-supplied injection point is a first-consumer-wins binding — under coroutines, which consumer wins is nondeterministic. compile() now rejects such bindings with SingletonRequiresInjectionPoint (the message is the dependency index). Use prototype scope instead. [#140]
Generated scripts also emit $ip ?? throw new InjectionPointNotAvailable, so resolving an injection-point binding without a consumer context fails with a dedicated exception instead of a bare TypeError.
Other changes
- Reject an unsafe dependency index instead of encoding it; escape the index and export serialized values in generated code [#139]
- Generated scripts no longer carry
// prototype/// singletonscope comments [#140] - Fix the singleton PostConstruct lifecycle: the injector caches itself, and a failed setter/
setContext()rolls back the provisional cache entry instead of leaving a half-initialized singleton [#138]
Upgrade notes
- If your module binds an injection-point-dependent provider as a singleton,
compile()now fails — change the binding to prototype scope. - Recompile your scripts with 1.15.0 before calling
warmup(); it throwsSingletonsFileNotFoundwhensingletons.jsonis missing.