Skip to content

Conversation

@NathanFlurry
Copy link
Member

No description provided.

@vercel
Copy link

vercel bot commented Nov 6, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
rivetkit-serverless Ready Ready Preview Comment Nov 6, 2025 5:38am
3 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
rivet-cloud Ignored Ignored Nov 6, 2025 5:38am
rivet-inspector Ignored Ignored Preview Nov 6, 2025 5:38am
rivet-site Ignored Ignored Preview Nov 6, 2025 5:38am

Copy link
Member Author

NathanFlurry commented Nov 6, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add the label merge-queue to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 6, 2025

More templates

@rivetkit/actor

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/actor@3391

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@3391

@rivetkit/core

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/core@3391

@rivetkit/db

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/db@3391

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@3391

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@3391

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@3391

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@3391

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@3391

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@3391

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@3391

commit: edf9f39

@graphite-app
Copy link
Contributor

graphite-app bot commented Nov 6, 2025

Merge activity

  • Nov 6, 5:47 AM UTC: NathanFlurry added this pull request to the Graphite merge queue.
  • Nov 6, 5:48 AM UTC: CI is running for this pull request on a draft pull request (#3395) due to your merge queue CI optimization settings.
  • Nov 6, 5:50 AM UTC: Merged by the Graphite merge queue via draft PR: #3395.

@claude
Copy link

claude bot commented Nov 6, 2025

PR Review: Fix hibernatable websocket last seen message index to be i64 instead of u64

Summary

This PR changes the BARE schema for hibernatable WebSocket persistence to use signed integers (i64) instead of unsigned integers (u64) for timestamp and message index fields. The changes are focused on maintaining consistency with the TypeScript runtime types and ensuring proper data serialization.

Code Quality ✅

Strengths:

  • Clean, focused change that addresses a specific type mismatch issue
  • Adds helpful debug logging for troubleshooting hibernatable WebSocket persistence
  • Error logging improvement in instance.ts:679-682 helps diagnose persist save failures

Schema Changes:
The BARE schema changes in v2.bare are systematic and consistent:

  • PersistedConnection.lastSeen: u64i64
  • PersistedScheduleEvent.timestamp: u64i64
  • PersistedHibernatableWebSocket.lastSeenTimestamp: u64i64
  • PersistedHibernatableWebSocket.msgIndex: u64i64

Potential Issues ⚠️

1. Type Safety Concern - Bigint Handling
In actor-driver.ts:196, there's a conversion that could be problematic:

lastMsgIndex: Number(existingWs.msgIndex),

The runtime type is bigint (per persisted.ts:45), but converting to Number can lose precision for values exceeding Number.MAX_SAFE_INTEGER (2^53 - 1). While message indices are unlikely to reach this limit in practice, the schema change from u64 to i64 doesn't eliminate this risk—it actually introduces the possibility of negative values.

Recommendation: Consider whether message indices should ever be negative. If not, add validation or use a safer conversion approach. At minimum, add a comment explaining the assumption.

2. Semantic Mismatch - Signed vs Unsigned
Message indices and timestamps are semantically non-negative quantities:

  • Timestamps are milliseconds since epoch (always ≥ 0)
  • Message indices are sequence numbers (always ≥ 0)

Using i64 instead of u64 allows invalid negative values to be stored. The runtime types (bigint in TypeScript) don't enforce non-negativity either.

Questions:

  • Is there a reason to use i64 over u64?
  • Does the BARE serialization library or engine have issues with u64?
  • Are there existing persist data files that need migration?

3. Timestamp Precision
Per actor-driver.ts:274 and actor-driver.ts:282, timestamps use BigInt(Date.now()), which produces millisecond precision. This is stored in an i64 field. Consider documenting the timestamp format (milliseconds since epoch) in the schema comments.

Performance ✅

The added debug logging is appropriately scoped and shouldn't impact performance meaningfully.

Security ✅

No security concerns identified. The changes are internal to the persistence layer.

Test Coverage ⚠️

Missing Test Coverage:
There don't appear to be tests specifically covering:

  1. Hibernatable WebSocket persistence roundtrip (serialize → deserialize)
  2. Message index boundary cases
  3. Migration from the old u64 schema to the new i64 schema

Recommendation: Add integration tests for hibernatable WebSocket persistence, especially for:

  • Message index handling across hibernation/wake cycles
  • Boundary values (0, negative, large positive)
  • Backward compatibility with existing persist data

Additional Observations

Debug Logging Added (Good):

  • actor-driver.ts:177-181: Logs existing hibernatable WebSocket count
  • actor-driver.ts:358-362: Logs persisted data write with size
  • actor-driver.ts:439-444: Logs persisted data load with size and source

These logs will be helpful for debugging hibernation issues.

Error Logging Added (Good):

  • instance.ts:679-682: Now logs errors when persist save fails before re-throwing

Questions for Author

  1. What motivated changing from u64 to i64? Was there a runtime issue or serialization bug?
  2. Are there existing actors with persisted data using the old u64 schema? If so, how is migration handled?
  3. Should we add validation to prevent negative values from being stored in these fields?
  4. Would it be valuable to add a test covering the hibernatable WebSocket persistence flow?

Overall Assessment

Verdict: Approve with suggestions

The changes are well-structured and focused. The shift to i64 appears intentional, though the rationale isn't clear from the PR description. The main concerns are:

  1. Potential precision loss in Number() conversion (though unlikely in practice)
  2. Semantic mismatch using signed integers for unsigned quantities
  3. Lack of test coverage for this critical persistence path

Suggested Next Steps:

  1. Add a comment explaining why i64 is used instead of u64
  2. Consider adding validation for non-negative values
  3. Add integration tests for hibernatable WebSocket persistence
  4. Document timestamp format in schema comments

Note: I noticed this PR is based on branch 11-05-fix_rivetkit_gracefully_call__onstop_for_actors_on_runner_shutdown. Make sure these changes are compatible with the base branch's functionality.

graphite-app bot pushed a commit that referenced this pull request Nov 6, 2025
@graphite-app graphite-app bot closed this Nov 6, 2025
@graphite-app graphite-app bot deleted the 11-05-fix_rivetkit_fix_hibernatable_websocket_last_seen_message_index_to_be_i64_instead_of_u64 branch November 6, 2025 05:50
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.

2 participants