bootstrap: address Copilot review — wording/naming for timeout path · Entire
bootstrap: address Copilot review — wording/naming for timeout path
0288391→main·
Soph·1mo ago·1 file·+13 added/-14 removed
The one-shot retry path and the mid-batch subdivision now fire on
receive-pack deadlines (408/504), not just size rejections, so the
rejection-centric log message, the sizeIssue variable name, and the
"rejected" wording in the actionable error were all misleading.
- Log message: "after target rejection" → "after batchable push failure"
(the per-call
reasonfield already distinguishes timeout vs rejection). - Rename
sizeIssue→subdivide, keyed on the shared remedy. - Actionable error: "rejected the pack" → "could not receive the pack — too large, or too slow to receive within its deadline".
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
460bf1c3228fView transcript
Changes
1
internal/strategy/bootstrap
Mbootstrap.go+13/-14
184 unmodified lines
185
186
187
188
188
189
190
191
310 unmodified lines
502
503
504
505
506
507
508
509
510
511
505
506
507
508
509
510
511
512
513
5 unmodified lines
519
520
521
523
522
523
525
524
525
526
527
946 unmodified lines
1474
1475
1476
1478
1477
1478
1479
1480
6 unmodified lines
1487
1488
1489
1491
1492
1493
1490
1491
1492
1493
1494
1495
184 unmodified lines
if isTargetPushDeadlineError(pushErr) {
reason = "target push timed out"
}
p.log("bootstrap retrying with batched mode after target rejection",
p.log("bootstrap retrying with batched mode after batchable push failure",
"target_max_pack_bytes", autoBatch, "reason", reason)
p.notice(fmt.Sprintf("%s — switching to batched mode (limit %s)",
reason, humanBytes(autoBatch)))
310 unmodified lines
abortedEarly := observer.Aborted()
if pushErr != nil {
_ = packReader.Close()
// Treat abortedEarly the same as a body-limit error:
// both indicate "this pack is too big for the target",
// just one is detected by the server and one by us. A
// receive-pack deadline (408/504) lands here too — a
// checkpoint that times out is also too big for this
// target/link, and subdividing makes each push finish sooner.
sizeIssue := abortedEarly || isBatchableTargetPushError(pushErr)
// A pack too big for the target is the unifying signal here,
// whether the server announced it (413 body limit), we
// detected it ourselves (abortedEarly), or the target ran out
// of time receiving it (408/504 deadline). All three are fixed
// the same way: subdivide so each push is smaller and faster.
subdivide := abortedEarly || isBatchableTargetPushError(pushErr)
p.log("bootstrap batch push failed",
"branch", batch.Plan.TargetRef.String(),
"batch", idx+1,
"objects_sent", objectsSent,
"total_objects_in_pack", totalObjects,
"aborted_early", abortedEarly,
"will_subdivide", sizeIssue && len(batch.chain) > 0,
"will_subdivide", subdivide && len(batch.chain) > 0,
"error", pushErr.Error())
if sizeIssue && len(batch.chain) > 0 {
if subdivide && len(batch.chain) > 0 {
parsedLimit := targetBodyLimit(pushErr)
limit := p.TargetMaxPack
if parsedLimit > 0 {
946 unmodified lines
}
// actionableTargetPushError augments a one-shot push failure with guidance
// when the target rejected the pack for being too large or slow but batched
// when the target couldn't receive the pack — too large or too slow — but batched
// bootstrap couldn't take over — which, on the one-shot path, means the source
// can't serve the protocol-v2 fetch filter that checkpointing requires. The
// extra context tells the user why the obvious knob (--target-max-pack-bytes)
if p.SourceService != nil && p.SourceService.SupportsBootstrapBatch() {
return err
}
return fmt.Errorf("%w (target rejected the pack as too large or too slow to receive; "+
"batched bootstrap could split it into smaller pushes, but the source does not "+
"support the protocol-v2 fetch filter batched bootstrap requires)", err)
return fmt.Errorf("%w (target could not receive the pack — too large, or too slow to "+
"receive within its deadline; batched bootstrap could split it into smaller pushes, "+
"but the source does not support the protocol-v2 fetch filter batched bootstrap requires)", err)
}
func targetBodyLimit(err error) int64 {