Skip to content

Go node: furrowd drops child output when Wait races the stdout copy; supervisor test reads empty PID file #161

Open

Description

@AbirAbbas

Two pre-existing races in the Go node turn up as intermittent go test -race failures in CI. Both reproduce on main and are independent of any open PR.

1. furrowd loses child output (cmd/furrowd, runChild). runChild starts io.Copy(conn, stdout) and calls cmd.Wait() concurrently, then waits for the copy. os/exec documents that Wait closes StdoutPipe, so it must not run before all reads finish. When the network write is slow, the tail of the child's output is dropped:

  • CI symptom (Treat Claude usage caps and expired logins as fatal #156's first run): TestHappyPathRoundTripThroughDialer got "MARKER:", want "MARKER:ciphertext" (main_test.go:103).
  • Also seen locally: TestChildServesRecordedStoreDirNotRawRunID returned an empty data dir (main_test.go:148), 4 failures in 20 runs on main.
  • A deterministic probe that delays the first write by 200ms reproduces it on main every time, with copy child output: read |0: file already closed.
  • Fix shape: wait for the copy goroutine to drain stdout before calling cmd.Wait().

2. internal/furrow supervisor test reads an empty PID file. In TestSupervisorCancellationKillsChildAndReturns (supervisor_test.go:167), waitForPID parses the file as soon as it exists, but the shell creates or truncates it before echo $$ writes the PID, which fails with strconv.Atoi: parsing "": invalid syntax. It reproduces in -count=10 runs on main. Fix shape: keep polling until the file contains a full line, or have the helper write to a temp file and rename it.

Item 1 is a real product bug: a slow client can lose the end of a child's output. Item 2 is only a test.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions