Skip to content

Commit bf15750

Browse files
myleshortonclaude
andcommitted
fix: address PR review — timer drain, header clone, doc comment
- Drain timer.C after Stop to prevent spurious immediate wake on first loop iteration (0-duration timer fires before Reset) - Clone header value slices in rewriteRequest to decouple from caller's request and prevent data races on retry - Update WithReadyQueueSize doc comment: default is 500, not 4000 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent daa94ae commit bf15750

2 files changed

Lines changed: 10 additions & 4 deletions

File tree

domainfront.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func WithClientHelloID(id tls.ClientHelloID) Option {
8080
func WithCrawlerConcurrency(n int) Option { return func(c *Client) { c.crawlerConcurrency = n } }
8181

8282
// WithReadyQueueSize sets the capacity of the ready-fronts channel.
83-
// Smaller values save memory on constrained devices. Default is 4000.
83+
// Smaller values save memory on constrained devices. Default is 500.
8484
func WithReadyQueueSize(n int) Option { return func(c *Client) { c.readyQueueSize = n } }
8585

8686
// WithCacheSaveInterval sets how often dirty cache state is flushed to disk.
@@ -246,7 +246,11 @@ func (c *Client) crawler() {
246246
// Use a reusable timer instead of time.After to avoid leaking timers.
247247
// time.After creates a new timer each iteration that isn't GC'd until it
248248
// fires — on memory-constrained devices this creates mounting GC pressure.
249+
// Initialize stopped and drain to avoid an immediate spurious wake.
249250
timer := time.NewTimer(0)
251+
if !timer.Stop() {
252+
<-timer.C
253+
}
250254
defer timer.Stop()
251255

252256
for {

roundtrip.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,13 @@ func rewriteRequest(req *http.Request, frontedHost string, body io.ReadCloser) *
143143
Header: make(http.Header, len(req.Header)),
144144
}).WithContext(req.Context())
145145

146-
// Share header value slices instead of copying them. This is safe because
147-
// the original request's headers aren't modified during the round trip.
146+
// Clone header value slices to decouple from the caller's request.
147+
// Sharing slices can cause data races if the original request is reused.
148148
for k, vs := range req.Header {
149149
if !strings.EqualFold(k, "Host") {
150-
r.Header[k] = vs
150+
cp := make([]string, len(vs))
151+
copy(cp, vs)
152+
r.Header[k] = cp
151153
}
152154
}
153155
return r

0 commit comments

Comments
 (0)