Skip to content

fix(rivetkit-core): chunk apply_batch puts/deletes at 128#5046

Merged
abcxff merged 1 commit into
mainfrom
05-12-fix_rivetkit-core_chunk_apply_batch_puts_deletes_at_128
May 13, 2026
Merged

fix(rivetkit-core): chunk apply_batch puts/deletes at 128#5046
abcxff merged 1 commit into
mainfrom
05-12-fix_rivetkit-core_chunk_apply_batch_puts_deletes_at_128

Conversation

@abcxff
Copy link
Copy Markdown
Contributor

@abcxff abcxff commented May 12, 2026

@railway-app
Copy link
Copy Markdown

railway-app Bot commented May 12, 2026

🚅 Deployed to the rivet-pr-5046 environment in rivet-frontend

Service Status Web Updated (UTC)
kitchen-sink ❌ Build Failed (View Logs) Web May 13, 2026 at 6:44 pm
website 😴 Sleeping (View Logs) Web May 13, 2026 at 9:30 am
frontend-cloud ❌ Build Failed (View Logs) Web May 12, 2026 at 12:51 pm
frontend-inspector ❌ Build Failed (View Logs) Web May 12, 2026 at 12:51 pm
ladle ❌ Build Failed (View Logs) Web May 12, 2026 at 12:51 pm
mcp-hub ✅ Success (View Logs) Web May 12, 2026 at 12:50 pm

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 12, 2026

PR Review: fix(rivetkit-core): chunk apply_batch puts/deletes at 128

Overview

This PR fixes a bug where persist_state could send more than 128 keys in a single apply_batch call, violating the engine-side MAX_KEYS = 128 limit enforced in engine/packages/pegboard/src/actor_kv/utils.rs. The fix chunks puts and deletes into 128-item slices and issues multiple sequential apply_batch calls.

Correctness

The chunking logic is correct. Looking at apply_batch in kv.rs, puts and deletes are already sent as separate batch_put / batch_delete RPC calls, so the 128-key limit applies to each list independently. The loop handles mismatched list lengths correctly: when one iterator is exhausted, unwrap_or returns an empty slice and the remaining chunks of the other list continue to be drained.

Issues

1. Missing test for the >128 key path

The existing test_apply_batch_call_count assertions in task.rs (lines ~1980, ~1998) all use small key counts well under 128, so they do not exercise the new code path. A test with 129+ ConnHibernation deltas in a single save_state call would confirm chunking works end-to-end and guard against regressions.

2. Payload size limit not addressed

The engine also enforces MAX_PUT_PAYLOAD_SIZE = 976 KiB per validate_entries. With 128 entries each near the 128 KiB per-value ceiling, a single chunk could still exceed this. For current use cases (connection hibernation data is small) this is unlikely to trigger, but worth noting as a latent failure mode.

3. Non-atomicity of chunked writes (acknowledged)

The TODO comment correctly describes the risk: a failure mid-loop leaves actor state partially persisted. The SQLite migration path in the TODO is the right long-term fix. No action needed now beyond the existing comment.

Minor Notes

  • Doc comment on APPLY_BATCH_CHUNK_SIZE correctly mirrors the engine constant and explains why it exists.
  • pub(crate) visibility is appropriate.
  • Comment style is consistent with CLAUDE.md conventions.

Summary

The fix is logically correct and the non-atomicity trade-off is properly called out. The main gap is test coverage: recommend adding a test that saves more than 128 ConnHibernation deltas in a single save_state call and verifies all entries are persisted.

@abcxff abcxff force-pushed the 05-07-fix_pegboard_validate_drain_grace_period_request_lifespan branch from aac9634 to f8fe5aa Compare May 12, 2026 13:21
@abcxff abcxff force-pushed the 05-12-fix_rivetkit-core_chunk_apply_batch_puts_deletes_at_128 branch from 7920c6d to 78dd055 Compare May 12, 2026 13:21
@railway-app railway-app Bot temporarily deployed to rivet-frontend / rivet-pr-5046 May 12, 2026 13:21 Destroyed
@abcxff abcxff force-pushed the 05-12-fix_rivetkit-core_chunk_apply_batch_puts_deletes_at_128 branch from 78dd055 to 741181f Compare May 12, 2026 13:29
@railway-app railway-app Bot temporarily deployed to rivet-frontend / rivet-pr-5046 May 12, 2026 13:29 Destroyed
Copy link
Copy Markdown
Contributor Author

abcxff commented May 13, 2026

Merge activity

  • May 13, 6:35 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 13, 6:44 PM UTC: Graphite rebased this pull request as part of a merge.
  • May 13, 6:44 PM UTC: @abcxff merged this pull request with Graphite.

@abcxff abcxff changed the base branch from 05-07-fix_pegboard_validate_drain_grace_period_request_lifespan to graphite-base/5046 May 13, 2026 18:41
@abcxff abcxff changed the base branch from graphite-base/5046 to main May 13, 2026 18:42
@abcxff abcxff force-pushed the 05-12-fix_rivetkit-core_chunk_apply_batch_puts_deletes_at_128 branch from 741181f to 3291dcc Compare May 13, 2026 18:43
@railway-app railway-app Bot temporarily deployed to rivet-frontend / rivet-pr-5046 May 13, 2026 18:43 Destroyed
@abcxff abcxff merged commit dd7eb21 into main May 13, 2026
10 of 12 checks passed
@abcxff abcxff deleted the 05-12-fix_rivetkit-core_chunk_apply_batch_puts_deletes_at_128 branch May 13, 2026 18:44
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