Skip to content

feat: basic envoy tunnel impl#4534

Draft
MasterPtato wants to merge 1 commit into03-27-chore_envoy_clientfrom
03-30-feat_basic_envoy_tunnel_impl
Draft

feat: basic envoy tunnel impl#4534
MasterPtato wants to merge 1 commit into03-27-chore_envoy_clientfrom
03-30-feat_basic_envoy_tunnel_impl

Conversation

@MasterPtato
Copy link
Copy Markdown
Contributor

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@railway-app
Copy link
Copy Markdown

railway-app bot commented Mar 31, 2026

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

Service Status Web Updated (UTC)
frontend-inspector 😴 Sleeping (View Logs) Web Mar 31, 2026 at 1:53 am
website 😴 Sleeping (View Logs) Web Mar 31, 2026 at 1:53 am
frontend-cloud 😴 Sleeping (View Logs) Web Mar 31, 2026 at 1:50 am
mcp-hub ✅ Success (View Logs) Web Mar 31, 2026 at 1:42 am
ladle ❌ Build Failed (View Logs) Web Mar 31, 2026 at 1:41 am
kitchen-sink ❌ Build Failed (View Logs) Web Mar 31, 2026 at 1:41 am

Copy link
Copy Markdown
Contributor Author

MasterPtato commented Mar 31, 2026

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 31, 2026

More templates

@rivetkit/virtual-websocket

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@4534

@rivetkit/cloudflare-workers

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

@rivetkit/framework-base

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

@rivetkit/next-js

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

@rivetkit/react

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

rivetkit

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

@rivetkit/sql-loader

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

@rivetkit/sqlite-vfs

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-vfs@4534

@rivetkit/traces

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

@rivetkit/workflow-engine

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/workflow-engine@4534

@rivetkit/engine-runner

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

@rivetkit/engine-runner-protocol

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

commit: 748e9f1

@claude
Copy link
Copy Markdown

claude bot commented Mar 31, 2026

Code Review: PR 4534 - feat: basic envoy tunnel impl

Summary: This draft PR implements a basic HTTP tunnel from Guard through the Envoy to actors, allowing actors to handle HTTP requests via the fetch callback. It also refactors startEnvoy to return an EnvoyHandle, adds eviction support on the connection task, and fixes several pre-existing bugs.


Critical Bugs

1. Map keys using array literals will never match

JavaScript Map uses reference equality for object/array keys. Two separately created arrays [gatewayId, requestId] will never be equal by reference, so .get() and .delete() always return undefined or false.

Affected files:

  • engine/sdks/typescript/envoy-client/src/tasks/envoy/tunnel.ts: ctx.requestToActor.get() and .delete()
  • engine/sdks/typescript/envoy-client/src/tasks/actor.ts: ctx.pendingRequests.get() and .set() and .delete()

The entire streaming request flow (request chunks and aborts) is silently broken. Fix: use a composite string key, e.g., idToStr(gatewayId) + ":" + idToStr(requestId) using the existing idToStr helper in utils.ts.

2. protocolMetadata maxPayloadSize references a non-existent field

In tunnel.ts line 83, the field maxPayloadSize does not exist on ProtocolMetadata. The correct field name is maxResponsePayloadSize. This comparison is always against undefined, so the payload size limit is never enforced.

3. requestToActor map is never populated

handleRequestStart forwards the message to the actor but never inserts into ctx.requestToActor. The map exists but has no .set() call, so subsequent request-chunk and request-abort messages always fail silently to find the associated actor.


Logic / Correctness Issues

4. startEnvoy can hang forever if init is never received

In engine/sdks/typescript/envoy-client/src/tasks/envoy/index.ts, startRx.changed() awaits indefinitely if the WebSocket connection fails before ToEnvoyInit is received. There is no timeout or error path.

5. Errors in spawned response handlers are silently dropped

In actor.ts lines 215 and 235, errors thrown inside spawn() (e.g., from sendResponse when body is too large) are not caught, so failed response sends go unlogged.

6. SIGINT handler logs SIGTERM

In test-envoy/src/index.ts, the SIGINT handler prints received SIGTERM instead of received SIGINT.


Code Quality Issues

7. Commented-out code in production files

Large blocks of commented-out code were committed and should be removed: the webSockets map and initialization in actor.ts, and the large streamSSE and WebSocket handler bodies in test-envoy/src/index.ts. Per project conventions, documenting removed code is not useful.

8. as any cast without explanation

actor.ts line 204 casts to any for duplex half which is not in standard RequestInit. The cast is necessary for a Node.js fetch quirk but deserves a comment.

9. let instead of const for variables never reassigned

tunnel.ts lines 50, 64: let actor = findActor() should be const.

10. Log level too alarming for expected reconnect window

connection.ts line 166: wsSend logs at error level when the WebSocket is not connected. During normal reconnect windows this is expected, so warn is more appropriate.


Rust Changes - Positive Observations

The Rust-side changes look clean and correct:

  • api-peer/src/actors/delete.rs: Moving namespace_res unwrap before the actor lookup is a correct ordering fix.
  • config/src/config/pegboard.rs: Renaming envoy_max_response_payload_body_size to envoy_max_response_payload_size is a clean simplification.
  • pegboard/src/workflows/actor2/mod.rs: The CheckEnvoyLivenessOutput struct correctly captures now at actual server time to prevent drift. The &mut fix on state.transition is a correctness fix.
  • gasoline/src/builder/common/workflow.rs: The added tracing::debug dispatched workflow log is useful observability.
  • guard/src/shared_state.rs: Running pegboard_gateway and pegboard_gateway2 concurrently via tokio::try_join is correct.
  • envoy-protocol/v1.bare: Adding maxResponsePayloadSize to ProtocolMetadata follows the established pattern.

Summary

Priority Issue
Critical Array literal keys in Map never match - streaming requests silently broken
Critical maxPayloadSize is wrong field name - size limit never enforced
Critical requestToActor map never populated - chunk/abort routing broken
High startEnvoy hangs forever if init never received
Medium Errors in spawned response handlers silently dropped
Low Commented-out code throughout
Low SIGINT handler logs SIGTERM instead of SIGINT
Low let instead of const

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