Skip to content

Conversation

@binaryfire
Copy link
Contributor

This PR ports Laravel's once() memoization helper to Hypervel, adapted for coroutine safety.

What's included

  • Once class - Stores memoized values using Context instead of static properties, ensuring per-coroutine isolation
  • Onceable class - Generates unique hashes from call traces to identify memoization targets
  • once() helper - Same as Laravel's API: once(fn () => expensive())
  • HasOnceHash contract - Allows objects to provide custom hash values for memoization

Coroutine safety

Laravel's implementation uses a static WeakMap which would leak state between concurrent requests in Swoole. This implementation stores the WeakMap in Context, so each coroutine gets its own isolated memoization cache.

// Each coroutine gets independent memoization
$result = once(fn () => $this->expensiveCalculation());

Tests

  • OnceTest - Verifies caching behavior and coroutine isolation
  • OnceableTest - Verifies trace-based hash generation and HasOnceHash support

Implements Once using Hyperf Context for per-coroutine isolation,
ensuring concurrent requests don't interfere with cached values.
Onceable captures caller context (file, line, class, object) to generate
unique hashes for memoization. Supports HasOnceHash interface for custom
hash implementations.
Memoizes callable results per-coroutine using the Once class.
Tests verify:
- Caching within coroutine
- Differentiation based on closure uses
- Coroutine isolation (parallel calls get independent results)
Tests verify:
- Caller object capture from trace
- HasOnceHash interface support for custom hash implementations
Allows objects to provide custom hash values for once() memoization
by implementing the HasOnceHash interface.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant