fix: address code review issues on PR #10 (HAN-384)
- runner.go: store fingerprints in local var, call formatter.SetFingerprints() instead of mutating caller's *Config; removes Fingerprints field from Config - fingerprint.go: use singleflight.Group in Query to coalesce concurrent probes for the same IP, eliminating the double-probe race - output layer: add SetFingerprints(map[string]string) to Formatter interface; textFormatter and jsonFormatter each hold their own fingerprints field - formatter_test.go: add TestTextFormatterWriteSummaryShowsVersions and TestJSONFormatterWriteSummaryShowsVersions verifying version output Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Copilot
multica-agent
parent
3e7580b919
commit
c96d18859f
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
miekgdns "github.com/miekg/dns"
|
||||
"golang.org/x/sync/singleflight"
|
||||
)
|
||||
|
||||
const defaultTimeout = 2 * time.Second
|
||||
@@ -17,6 +18,7 @@ type Fingerprinter struct {
|
||||
mu sync.Mutex
|
||||
cache map[string]string
|
||||
timeout time.Duration
|
||||
group singleflight.Group
|
||||
exchange func(ctx context.Context, addr string, m *miekgdns.Msg) (*miekgdns.Msg, error)
|
||||
}
|
||||
|
||||
@@ -36,6 +38,8 @@ func NewWithTimeout(timeout time.Duration) *Fingerprinter {
|
||||
// Query returns the version string for ip, or "" if the server doesn't
|
||||
// respond or doesn't support the version.bind CHAOS query.
|
||||
// Results are cached: subsequent calls for the same IP return immediately.
|
||||
// Concurrent calls for the same IP are coalesced via singleflight so only
|
||||
// one network probe is issued per IP at a time.
|
||||
func (f *Fingerprinter) Query(ctx context.Context, ip net.IP) string {
|
||||
key := ip.String()
|
||||
|
||||
@@ -46,13 +50,15 @@ func (f *Fingerprinter) Query(ctx context.Context, ip net.IP) string {
|
||||
}
|
||||
f.mu.Unlock()
|
||||
|
||||
version := f.probe(ctx, ip)
|
||||
v, _, _ := f.group.Do(key, func() (interface{}, error) {
|
||||
version := f.probe(ctx, ip)
|
||||
f.mu.Lock()
|
||||
f.cache[key] = version
|
||||
f.mu.Unlock()
|
||||
return version, nil
|
||||
})
|
||||
|
||||
f.mu.Lock()
|
||||
f.cache[key] = version
|
||||
f.mu.Unlock()
|
||||
|
||||
return version
|
||||
return v.(string)
|
||||
}
|
||||
|
||||
// FingerprintAll queries all ips concurrently and returns a map of
|
||||
|
||||
Reference in New Issue
Block a user