Skip to content

proxy: add opt-in immediate batch forwarding - #147

Open
HashimTheArab wants to merge 11 commits into
stablefrom
batch-forwarding
Open

proxy: add opt-in immediate batch forwarding#147
HashimTheArab wants to merge 11 commits into
stablefrom
batch-forwarding

Conversation

@HashimTheArab

@HashimTheArab HashimTheArab commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add opt-in batch forwarding capabilities for proxy listeners
  • preserve packet order and flush once per received client/backend batch
  • document the latency and CPU/bandwidth tradeoff
  • pin the merged gophertunnel batch-reading implementation

When enabled, forwarding no longer waits for the independent 50 ms flush timers. This removes 0–50 ms of buffering in each direction (about 50 ms average round-trip reduction, depending on timer alignment). The default remains disabled so existing users retain 50 ms coalescing and its CPU/compression benefits.

Verification

  • go test ./...
  • (cd example/default && go test ./...)
  • go test -race ./integration/proxy
  • go mod tidy -diff in the root and example module
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Added an opt-in batch forwarding mode for the standalone proxy.
    • Preserves packet order and immediately flushes forwarded batches to reduce latency.
    • Includes capability checks to prevent use with incompatible connections.
  • Documentation

    • Added setup guidance, configuration examples, and notes about default behavior and potential resource trade-offs.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0ebf89db-5fad-4dbd-8648-ed1eb45e4ce2

📥 Commits

Reviewing files that changed from the base of the PR and between ce3d96f and 825a4cd.

📒 Files selected for processing (1)
  • integration/proxy/proxy_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • integration/proxy/proxy_test.go

📝 Walkthrough

Walkthrough

The standalone RakNet proxy gains opt-in batch forwarding with capability checks, immediate batch writes, ordered packet handling, and transfer-aware backend processing. Tests cover the new behavior, while Go dependencies and setup documentation are updated.

Changes

Standalone batch forwarding

Layer / File(s) Summary
Batch forwarding contract and runtime wiring
integration/proxy/proxy.go
Adds EnableBatchForwarding, batch capability interfaces, batch-read configuration, and session capability validation.
Batch forwarding and transfer handling
integration/proxy/proxy.go
Adds client and backend batch loops that rewrite packets, preserve order, immediately flush batches, and stop forwarding at transfers.
Batch behavior validation
integration/proxy/proxy_test.go
Tests default behavior, capability rejection, ordered writes, empty flushes, transfer handling, and fake batch transports.
Dependency and setup updates
go.mod, example/default/go.mod, docs/setup.md
Refreshes Go and module versions and documents the experimental batch-forwarding option and its standalone proxy scope.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ProxySession
  participant Backend
  Client->>ProxySession: ReadBatch
  ProxySession->>ProxySession: Rewrite and handle packets
  ProxySession->>Backend: WritePacketImmediate
  Backend->>ProxySession: ReadBatch
  ProxySession->>ProxySession: Handle transfer packet
  ProxySession->>Client: WritePacketImmediate
Loading

Possibly related PRs

  • oomph-ac/oomph#139: Introduces the standalone proxy structure extended by this batch-forwarding implementation.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately highlights the main change: an opt-in immediate batch forwarding mode for the proxy.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch batch-forwarding

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
example/default/default.go (1)

29-32: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Make the example’s opt-in behavior explicit.

EnableBatchForwarding defaults to false, but this checked-in example enables it, so users following the documented startup command receive immediate forwarding and its CPU/bandwidth trade-off. Either document that the example intentionally opts in or keep the flag false if this example is meant to represent defaults.

🤖 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 `@example/default/default.go` around lines 29 - 32, Clarify the intended
default behavior in the example configuration around EnableBatchForwarding:
either remove the explicit true value so the example preserves the field’s false
default, or add nearby documentation explaining that the example intentionally
opts into immediate forwarding and its CPU/bandwidth trade-off.
integration/proxy/proxy_test.go (1)

322-345: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate ReadBatch/WritePacketImmediate logic between fakeBatchBackend and fakeBatchClient.

Both fakes implement identical queue-draining ReadBatch and copy-on-write WritePacketImmediate bodies. Extracting a shared embeddable recorder removes the duplication.

♻️ Proposed refactor: shared batch recorder
+type batchRecorder struct {
+	batches   [][]packet.Packet
+	immediate [][]packet.Packet
+}
+
+func (b *batchRecorder) ReadBatch() ([]packet.Packet, error) {
+	if len(b.batches) == 0 {
+		return nil, io.EOF
+	}
+	batch := b.batches[0]
+	b.batches = b.batches[1:]
+	return batch, nil
+}
+
+func (b *batchRecorder) WritePacketImmediate(packets ...packet.Packet) error {
+	b.immediate = append(b.immediate, append([]packet.Packet(nil), packets...))
+	return nil
+}
+
 type fakeBatchBackend struct {
 	*fakeBackend
-	batches   [][]packet.Packet
-	immediate [][]packet.Packet
+	batchRecorder
 }

 func newFakeBatchBackend() *fakeBatchBackend {
 	return &fakeBatchBackend{fakeBackend: &fakeBackend{}}
 }

-func (f *fakeBatchBackend) ReadBatch() ([]packet.Packet, error) {
-	if len(f.batches) == 0 {
-		return nil, io.EOF
-	}
-	batch := f.batches[0]
-	f.batches = f.batches[1:]
-	return batch, nil
-}
-
-func (f *fakeBatchBackend) WritePacketImmediate(packets ...packet.Packet) error {
-	f.immediate = append(f.immediate, append([]packet.Packet(nil), packets...))
-	return nil
-}

Apply the analogous change to fakeBatchClient (drop its own ReadBatch/WritePacketImmediate and embed batchRecorder instead).

Also applies to: 358-381

🤖 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 `@integration/proxy/proxy_test.go` around lines 322 - 345, Extract the shared
queue-draining ReadBatch and copy-on-write WritePacketImmediate behavior into an
embeddable batchRecorder type. Embed batchRecorder in fakeBatchBackend and
fakeBatchClient, remove their duplicate method implementations and redundant
state, and preserve the existing EOF and packet-recording behavior.
🤖 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.

Nitpick comments:
In `@example/default/default.go`:
- Around line 29-32: Clarify the intended default behavior in the example
configuration around EnableBatchForwarding: either remove the explicit true
value so the example preserves the field’s false default, or add nearby
documentation explaining that the example intentionally opts into immediate
forwarding and its CPU/bandwidth trade-off.

In `@integration/proxy/proxy_test.go`:
- Around line 322-345: Extract the shared queue-draining ReadBatch and
copy-on-write WritePacketImmediate behavior into an embeddable batchRecorder
type. Embed batchRecorder in fakeBatchBackend and fakeBatchClient, remove their
duplicate method implementations and redundant state, and preserve the existing
EOF and packet-recording behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a5999f9a-1f7e-4b4f-b896-2091ec6f9410

📥 Commits

Reviewing files that changed from the base of the PR and between 27c3613 and ce3d96f.

⛔ Files ignored due to path filters (2)
  • example/default/go.sum is excluded by !**/*.sum
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (6)
  • docs/setup.md
  • example/default/default.go
  • example/default/go.mod
  • go.mod
  • integration/proxy/proxy.go
  • integration/proxy/proxy_test.go

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