Skip to content

Implement BatchCommand: send all spans per request as a single wire message#326

Open
jrothrock wants to merge 4 commits into
masterfrom
batch-command
Open

Implement BatchCommand: send all spans per request as a single wire message#326
jrothrock wants to merge 4 commits into
masterfrom
batch-command

Conversation

@jrothrock
Copy link
Copy Markdown
Collaborator

Summary

  • Closes Batched request sending to core-agent #122
  • All commands for a single HTTP request (StartRequest, StartSpan, TagSpan, StopSpan, TagRequest, FinishRequest) are now assembled into one BatchCommand message and sent in a single write to the core-agent socket, matching the Python agent's wire format
  • V1BatchCommand request/response classes added; ScoutSpan.buildCommands() recursively builds the flat command list for a span tree; ScoutRequest.send() replaces the individual-send chain with batch assembly

Wire format produced

{
  "BatchCommand": {
    "commands": [
      { "StartRequest": { "request_id": "req-...", "timestamp": "..." } },
      { "TagRequest":   { "request_id": "req-...", "tag": "path", "value": "/" } },
      { "StartSpan":    { "request_id": "req-...", "span_id": "span-...", "operation": "Controller/home" } },
      { "TagSpan":      { "span_id": "span-...", "tag": "db.statement", "value": "SELECT 1" } },
      { "StopSpan":     { "span_id": "span-..." } },
      { "FinishRequest":{ "request_id": "req-..." } }
    ]
  }
}

Test plan

  • Added e2e test "Request with spans is sent as a single BatchCommand wire message" to test/scout/index.e2e.ts
    • Verifies exactly one BatchCommand message is received by the mock agent
    • Verifies zero standalone StartRequest / FinishRequest / StartSpan / StopSpan messages
    • Verifies the commands array contains StartRequest, FinishRequest, StartSpan, StopSpan, TagSpan, TagRequest
    • Verifies StartRequest appears before FinishRequest
  • Full existing test suite: 84/84 passing

🤖 Generated with Claude Code

jrothrock and others added 4 commits May 29, 2026 16:39
The core-agent is now launched with --daemonize true so the binary
forks itself into a true daemon. No PID is retained by the worker.

Fixes two related cluster bugs:

1. Always-spawns bug: start() now returns early when peerRunning()
   is true instead of calling startProcess() unconditionally. Each
   worker that starts after the first simply connects to the already-
   running daemon.

2. Cluster-shutdown bug (issue #117): stopProcess() is now a no-op.
   Workers can no longer kill the shared core-agent when shutting
   down or crashing, which previously took down Scout for all other
   workers in the cluster until a replacement was spawned.

This mirrors how the Python agent handles the core-agent lifecycle:
launch it, forget the PID, let the daemon manage itself.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… instantly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rker-owned

stopProcess() is now a no-op; no worker can kill the shared daemon.
allowShutdown had no documented behavior and no remaining effect.
Stripped from ScoutConfiguration type and all test callsites.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…essage

Instead of sending StartRequest, StartSpan, TagSpan, StopSpan, TagRequest,
and FinishRequest individually over the socket, ScoutRequest.send() now
assembles all commands for a request into a single BatchCommand message and
sends it in one write. This matches the Python agent's wire format and reduces
N round-trips to the core-agent to one per request.

- V1BatchCommand request class wraps a commands array into {"BatchCommand": {...}}
- V1BatchCommandResponse parses the agent's acknowledgement
- ScoutSpan.buildCommands() recursively collects StartSpan, child spans,
  TagSpan, and StopSpan for a span tree
- ScoutRequest.send() replaced with batch assembly path; emits RequestSent
  after the single BatchCommand response is received
- e2e test verifies exactly one BatchCommand is sent per transaction and that
  no standalone StartRequest/FinishRequest/Span messages appear

Closes #122

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

Batched request sending to core-agent

1 participant