Skip to content

Another attempt to fix conformance slowness#1023

Merged
tomusdrw merged 1 commit into
mainfrom
td-fjall-fast-partition-reset
Jul 9, 2026
Merged

Another attempt to fix conformance slowness#1023
tomusdrw merged 1 commit into
mainfrom
td-fjall-fast-partition-reset

Conversation

@tomusdrw

@tomusdrw tomusdrw commented Jul 9, 2026

Copy link
Copy Markdown
Member

No description provided.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for reusing a shared database keyspace across runs, improving database reuse in worker and fuzzing flows.
    • Added the ability to delete and recreate database partitions cleanly.
  • Bug Fixes

    • Pruning work now runs in order and is awaited before shutdown, reducing the risk of incomplete cleanup.
    • Shared database resources are no longer closed prematurely when reused by multiple components.
  • Tests

    • Added coverage for partition deletion and shared keyspace reuse behavior.

Walkthrough

This PR changes fjall-backed pruning in FjallBlocks and FjallStates to sequentially queue prune operations via a pendingPrune promise chain, awaited on close(). It adds FjallRoot.deletePartition, bumps the @fjall-js/fjall dependency, and introduces keyspace-sharing via ownsRoot tracking in FjallValuesSession and new fromRoot factories in HybridSerializedStates. Fuzz/importer/worker-config code is rewired to reuse a shared FjallRoot keyspace (with partition recycling) instead of a shared FjallValuesSession, with corresponding tests added.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • FluffyLabs/typeberry#1010: Refactors the same session-based reuse (FjallValuesSession/HybridSerializedStates.fromSession) that this PR converts to keyspace-level sharing.
  • FluffyLabs/typeberry#1002: Establishes the HybridSerializedStates + FjallRoot foundation that this PR's fromRoot/close changes build on.
  • FluffyLabs/typeberry#1019: Modifies the same fuzz resetState persistent fjall-hybrid reuse/reset logic in main-fuzz.ts.

Suggested reviewers: skoszuta, mateuszsikora

Poem

A rabbit hops through keyspaces deep,
No more sessions to lose or keep,
Prunes now queue in tidy rows,
While shared roots close as ownership shows,
Hop, hop, hooray — the burrow stays neat! 🐇✨

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (1 warning, 2 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title mentions a slowness fix, but it is generic and doesn't describe the fjall keyspace and partition-reset changes. Use a more specific title that names the main change, such as fjall keyspace reuse and partition reset improvements.
Description check ❓ Inconclusive No description was provided, so there isn't enough detail to assess whether it summarizes the changes. Add a brief description of the main code changes and their intent.
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch td-fjall-fast-partition-reset

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/workers/api-node/config.ts (1)

99-148: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Await blocks.close() and states.close() before releasing the keyspace
FjallBlocks and FjallStates both drain pendingPrune in close(). Skipping those calls can leave prune removals in flight when the shared-keyspace path tears down or deletes partitions, so the pruned entries may never be removed cleanly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/workers/api-node/config.ts` around lines 99 - 148, The openDatabase
flow in config.ts closes the underlying Fjall keyspace without first closing the
opened FjallBlocks and FjallStates instances, so their pendingPrune work can be
dropped. Update openDatabase’s cleanup path, especially the returned close
method and the error handling around the Promise.all opening block, to await
blocks.close() and states.close() before calling fjall.close() or releasing the
shared keyspace; use the existing blocks, states, and ownsFjall symbols to keep
the teardown order correct.
🧹 Nitpick comments (1)
packages/jam/database-fjall/blocks.ts (1)

90-104: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate prune-queue pattern shared with FjallStates.

The same pendingPrune chaining/close pattern is duplicated verbatim in packages/jam/database-fjall/states.ts (Lines 89-100). Consider extracting a small shared helper (e.g. a PruneQueue utility with enqueue(fn)/close()) to avoid maintaining two copies of this logic.

♻️ Sketch of a shared helper
// e.g. packages/jam/database-fjall/prune-queue.ts
export class PruneQueue {
  private pending: Promise<unknown> = Promise.resolve();

  enqueue(op: () => Promise<unknown>, onError: (e: unknown) => void): void {
    this.pending = this.pending.then(op).catch(onError);
  }

  async close(): Promise<void> {
    await this.pending;
  }
}

Then in FjallBlocks:

-  private pendingPrune: Promise<unknown> = Promise.resolve();
+  private readonly pruneQueue = new PruneQueue();
...
   markUnused(hash: HeaderHash): void {
-    this.pendingPrune = this.pendingPrune
-      .then(() =>
-        Promise.all([...]),
-      )
-      .catch((e) => logger.warn`Failed to prune block ${hash}: ${e}`);
+    this.pruneQueue.enqueue(
+      () => Promise.all([...]),
+      (e) => logger.warn`Failed to prune block ${hash}: ${e}`,
+    );
   }

   async close() {
-    await this.pendingPrune;
+    await this.pruneQueue.close();
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/jam/database-fjall/blocks.ts` around lines 90 - 104, The prune-queue
logic in FjallBlocks.markUnused and close is duplicated in FjallStates, so
extract the shared pendingPrune chaining and shutdown behavior into a small
reusable helper such as PruneQueue with enqueue and close methods. Update
FjallBlocks to use that helper instead of maintaining its own promise chain and
error handling, and apply the same shared utility in FjallStates so both classes
reuse one implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/workers/api-node/config.ts`:
- Around line 99-148: The openDatabase flow in config.ts closes the underlying
Fjall keyspace without first closing the opened FjallBlocks and FjallStates
instances, so their pendingPrune work can be dropped. Update openDatabase’s
cleanup path, especially the returned close method and the error handling around
the Promise.all opening block, to await blocks.close() and states.close() before
calling fjall.close() or releasing the shared keyspace; use the existing blocks,
states, and ownsFjall symbols to keep the teardown order correct.

---

Nitpick comments:
In `@packages/jam/database-fjall/blocks.ts`:
- Around line 90-104: The prune-queue logic in FjallBlocks.markUnused and close
is duplicated in FjallStates, so extract the shared pendingPrune chaining and
shutdown behavior into a small reusable helper such as PruneQueue with enqueue
and close methods. Update FjallBlocks to use that helper instead of maintaining
its own promise chain and error handling, and apply the same shared utility in
FjallStates so both classes reuse one implementation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f4cb6dcf-c7f5-4b18-ad02-f14b2a59795c

📥 Commits

Reviewing files that changed from the base of the PR and between 829b7ea and 2e6dea7.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • packages/jam/database-fjall/blocks.ts
  • packages/jam/database-fjall/hybrid-states.ts
  • packages/jam/database-fjall/package.json
  • packages/jam/database-fjall/root.test.ts
  • packages/jam/database-fjall/root.ts
  • packages/jam/database-fjall/states.ts
  • packages/jam/node/main-fuzz.ts
  • packages/jam/node/main-importer.ts
  • packages/workers/api-node/config.test.ts
  • packages/workers/api-node/config.ts

@tomusdrw tomusdrw merged commit 411c828 into main Jul 9, 2026
16 of 17 checks passed
@tomusdrw tomusdrw deleted the td-fjall-fast-partition-reset branch July 9, 2026 20:00
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