Conversation
|
Hey @WendellAdriel, thanks! I'm pretty sure I added this for performance reasons, let me run some benchmarks and see if we can safely drop it. Either way, if the issue is that blaze runtime retains stale data wouldn't a more direct solution be to make the runtime scoped? Or flush the data when request finishes? |
|
@ganyicz good point. |
|
Can you take a look in this new approach @ganyicz ? |
Remove ??= caching on $errors — always read fresh from the view factory. The previous approach (resetting via terminating callback) didn't cover all long-lived environments. Reading fresh costs ~135ns per component, which is negligible since each component reads $errors exactly once. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This reverts commit 6a808d9.
|
K, thought the approach and had a bunch of Claude instances try some different approaches and investigate and came up with this: (which I agree with and think we should go with)
|
|
If you're totally against even the tiniest amount of performance loss here, we could just go with terminating or another listener along those lines. But I say we just go with it. Thanks @WendellAdriel |
|
Thanks @calebporzio! 💪 My first approach was to remove the cache as well, but after talking with @ganyicz we were a little concerned about performance, if you feel it's ok, I'm ok on removing the cache. |
Issue
`BlazeRuntime` is a singleton shared across all views via `View::share('__blaze', ...)`. Blaze-compiled components (like `flux:error`) access `$errors` through `$__blaze->errors`, which triggers the `__get` magic method.
The original code was:
```php
return $this->errors ??= $this->env->shared('errors') ?? new ViewErrorBag;
```
The `??=` operator assigned the `$errors` value to a protected property on first access, then returned the cached value on all subsequent accesses. Since `BlazeRuntime` is a singleton, this meant:
@oncedirective as a validation check & extra test cases #2 (POST /login fails, redirect back with errors) — `ShareErrorsFromSession` middleware shares fresh errors into the view factory, but `$__blaze->errors` still returns the stale empty cached valueThis only manifests in long-lived processes (Pest Browser's in-process HTTP server, Laravel Octane, etc.) because in standard PHP-FPM each request gets a fresh process and singleton.
Fix
Remove the `??=` caching entirely — always read fresh from the view factory via `$this->env->shared('errors')`. Also removed the `protected ViewErrorBag $errors` property since it's no longer used.
The `shared()` call costs ~135ns per component, which is negligible since each component reads `$errors` exactly once (Wrapper.php stores it in a local variable). This approach fixes all long-lived environments without relying on lifecycle hooks.
How to replicate issue
Using the Laravel Livewire starter kit, create browser tests that first successfully login, then attempt a failed login. The second test never sees validation errors because the singleton cached an empty error bag from the first request.