Improved performance of distributed read endpoint (#42810)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #42808 

This is another hot path optimization recommended by Claude Code. I QA'd
it with a local osquery perf run.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.

## Testing

- [x] QA'd all new/changed functionality manually

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Enhanced performance of the distributed read endpoint by optimizing
lock contention management during jitter table access operations. This
change reduces latency and improves system responsiveness when handling
distributed read requests, particularly benefiting high-concurrency
scenarios. The optimization maintains all existing functionality while
providing better performance characteristics for read-heavy workloads.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Victor Lyuboslavsky
2026-04-03 07:13:56 -05:00
committed by GitHub
parent 49eead2461
commit fc58f60a83
4 changed files with 18 additions and 10 deletions
+13 -6
View File
@@ -849,15 +849,22 @@ func (svc *Service) hostRequiresConditionalAccessMicrosoftIngestion(ctx context.
}
func (svc *Service) shouldUpdate(lastUpdated time.Time, interval time.Duration, hostID uint) bool {
svc.jitterMu.Lock()
defer svc.jitterMu.Unlock()
svc.jitterMu.RLock()
jh := svc.jitterH[interval]
svc.jitterMu.RUnlock()
if svc.jitterH[interval] == nil {
svc.jitterH[interval] = newJitterHashTable(int(int64(svc.config.Osquery.MaxJitterPercent) * int64(interval.Minutes()) / 100.0))
svc.logger.DebugContext(context.TODO(), "jitter table created", "bucketCount", svc.jitterH[interval].bucketCount)
if jh == nil {
svc.jitterMu.Lock()
// Double-check after acquiring write lock.
if svc.jitterH[interval] == nil {
svc.jitterH[interval] = newJitterHashTable(int(int64(svc.config.Osquery.MaxJitterPercent) * int64(interval.Minutes()) / 100.0))
svc.logger.DebugContext(context.TODO(), "jitter table created", "bucketCount", svc.jitterH[interval].bucketCount)
}
jh = svc.jitterH[interval]
svc.jitterMu.Unlock()
}
jitter := svc.jitterH[interval].jitterForHost(hostID)
jitter := jh.jitterForHost(hostID)
cutoff := svc.clock.Now().Add(-(interval + jitter))
return lastUpdated.Before(cutoff)
}
+2 -2
View File
@@ -1253,7 +1253,7 @@ func TestHostDetailQueries(t *testing.T) {
logger: slog.New(slog.DiscardHandler),
config: config.TestConfig(),
ds: ds,
jitterMu: new(sync.Mutex),
jitterMu: new(sync.RWMutex),
jitterH: make(map[time.Duration]*jitterHashTable),
}
@@ -2296,7 +2296,7 @@ func TestMDMQueries(t *testing.T) {
logger: slog.New(slog.DiscardHandler),
config: config.TestConfig(),
ds: ds,
jitterMu: new(sync.Mutex),
jitterMu: new(sync.RWMutex),
jitterH: make(map[time.Duration]*jitterHashTable),
}
+2 -2
View File
@@ -48,7 +48,7 @@ type Service struct {
authz *authz.Authorizer
jitterMu *sync.Mutex
jitterMu *sync.RWMutex
jitterH map[time.Duration]*jitterHashTable
geoIP fleet.GeoIP
@@ -172,7 +172,7 @@ func NewService(
failingPolicySet: failingPolicySet,
authz: authorizer,
jitterH: make(map[time.Duration]*jitterHashTable),
jitterMu: new(sync.Mutex),
jitterMu: new(sync.RWMutex),
geoIP: geoIP,
enrollHostLimiter: enrollHostLimiter,
depStorage: depStorage,