Repository navigation
perf(runtime): read state synchronously - #64
Merged
Merged
Conversation
The native EVM call is synchronous, but the runtime gave createStorageView an async getter. Each cache miss ran Effect.runPromise, and each leaf read in a route was an await. The getter is now sync and runs Effect.runSync(evm.readStorage(...)), so app.state and app.accounts reads return values, not promises. A route now reads state with no yield point between reads, so it sees one snapshot. Before, the batch loop could execute a mutation between two awaits, and a route could read a length from one state and the elements from the next. Remove the semaphore in createEVM. Each native call blocks the thread, so calls cannot overlap without it. With the semaphore, a fiber could yield to the scheduler while it held the permit, and runSync on a storage read then failed with AsyncFiberError. A new test pauses a call at each op and makes sure runSync still completes. The order-book and token routes no longer await storage reads.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The native EVM call is synchronous, but the runtime gave
createStorageViewan async getter. Each cache miss ranEffect.runPromise, and each leaf read in a route was anawait. The getter is now sync and runsEffect.runSync(evm.readStorage(...)). Thusapp.stateandapp.accountsreads return values, not promises.lengthfrom one state and the elements from the next.createEVM. Each native call blocks the thread, so calls cannot overlap without a lock. With the semaphore, a fiber could yield to the scheduler (every 2048 ops by default) while it held the permit.runSyncon a storage read then failed withAsyncFiberError. Keep native methods synchronous: an async native method needs calls to be serialized again.Promise.allcalls around storage reads are gone.Breaking change
app.stateandapp.accountsleaf reads and dynamic arraylengthchange type fromPromise<T>toT. Code that only usesawaiton them still works. Code that calls.then()on a read, or gives a read toEffect.promise, fails.Test plan
bun run typecheck,bun run test(all six packages pass)biome checkon the changed files.bun run lintat the root stops on a nestedbiome.jsonin an untracked local worktree under.claude/, which is not in this PR.runSync completes while another call is paused mid-call. It fails withAsyncFiberErroragainst the semaphore version ofcreateEVMand passes on this branch.🤖 Generated with Claude Code

Confidence Score: 5/5
The PR appears safe to merge.Summary
This PR makes local state reads synchronous.
No actionable issues were found. Tests were inspected but not run.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR Route[Route reads a leaf] --> View[Storage view] View --> Cache{Slot cached?} Cache -->|Yes| Decode[Decode value] Cache -->|No| Sync[Effect.runSync] Sync --> Native[Synchronous native call] Native --> Store[Cache returned slots] Store --> Decode Decode --> Value[Return value without await]Reviews (1) · Last reviewed commit: "perf(runtime): read state synchronously" · Reviewed by Greptile