The write-deadline-kill predicate is copied per format package, and its two callers admit different endings
What
Two format packages carry a byte-identical predicate that decides whether a failed response write was the write deadline expiring or the client going away:
remoteTarballWriteDeadlineKillininternal/format/npm/remote_tarball.goblobFillWriteDeadlineKillininternal/format/oci/remote_blob.go
Both take (err error, deadline time.Time), answer true past the armed
instant, and fall back to errors.As(err, &netErr) && netErr.Timeout() when the
instant is the zero value because arming failed.
The duplication is correct as things stand. ADR-023 has format packages copy rather than import from each other, and the OCI copy's doc comment names the npm original. Nothing here proposes deleting either one on its own.
What is worth tracking
The two are changed together whether or not anyone notices, and so far nobody has. The same defect family has now been found twice, once per package, by two different reviews:
- #832: on the npm route the deadline-kill arm claims an upstream stall, because
the stall reports
Timeout() == truewhile the armed instant is still in the future. - On the OCI blob route the read arm claimed a client hangup, because a cancellation aborts the body read and arrives wrapped exactly like an upstream that stopped sending. Fixed in Step 15 part 2 of the S16 container remote work by admitting only a live request context to that arm.
Both are the same shape — an arm claiming an ending that belongs to another party — and in both cases the predicate is right and the caller is what decides what may reach it. Neither fix reached the other package, because nothing links the copies beyond one doc sentence.
Proposal
Two parts, and the second is the one with a decision in it:
- Record the pairing where a reader will meet it. Each copy's doc names the other, and each names what its own caller admits: the npm caller lets the upstream's reads reach the predicate, the OCI caller does not. That asymmetry is why npm names its counter for what the arm books rather than for the deadline, and it is the thing a reader has to know before copying either one again.
- Decide whether a shared home is wanted. If a package for the relay-side primitives these routes share ever lands, both predicates collapse into it and ADR-023's copy rule stops applying, because the shared package would not be a format package. Until then the copies stay and part 1 is the whole of the work. Adopting a shared home is an ADR-023 conversation, not a refactor somebody can land quietly.