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.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ports Laravel's once() memoization helper to Hypervel, adapted for coroutine safety by using Context instead of static properties for storage isolation.

Changes:

  • Adds the once() helper function that caches callable results based on call location and context
  • Implements coroutine-safe memoization using Hypervel's Context system instead of static properties
  • Includes comprehensive tests for caching behavior, coroutine isolation, and hash generation

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/support/src/Once.php Main memoization class storing cached values in WeakMap within Context for coroutine isolation
src/support/src/Onceable.php Generates unique hashes from call traces and closure variables to identify memoization targets
src/support/src/Contracts/HasOnceHash.php Interface allowing objects to provide custom hash values for memoization
src/support/src/helpers.php Adds the once() helper function with Laravel-compatible API
tests/Support/OnceTest.php Tests caching behavior, closure differentiation, and coroutine-scoped isolation
tests/Support/OnceableTest.php Tests trace-based object capture and HasOnceHash implementation
src/horizon/src/ProcessInspector.php Removes redundant PHPDoc type annotation
src/console/src/Scheduling/ManagesFrequencies.php Fixes incorrect duplicate type in docblock parameter

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@albertcht albertcht merged commit c06d2f9 into hypervel:main Jan 27, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants