Compact runs until the number of channels in the cache is lower than compactLowWatermark
(ctx context.Context)
| 453 | |
| 454 | // Compact runs until the number of channels in the cache is lower than compactLowWatermark |
| 455 | func (c *channelCacheImpl) compactChannelCache(ctx context.Context) { |
| 456 | defer c.compactRunning.Set(false) |
| 457 | |
| 458 | // Increment compact count on start, as timing is updated per loop iteration |
| 459 | c.cacheStats.ChannelCacheCompactCount.Add(1) |
| 460 | |
| 461 | cacheSize := c.channelCaches.Length() |
| 462 | base.InfofCtx(ctx, base.KeyCache, "Starting channel cache compaction, size %d", cacheSize) |
| 463 | for { |
| 464 | // channelCache close handling |
| 465 | compactIterationStart := time.Now() |
| 466 | |
| 467 | select { |
| 468 | case <-c.terminator: |
| 469 | base.DebugfCtx(ctx, base.KeyCache, "Channel cache compaction stopped due to cache close.") |
| 470 | return |
| 471 | default: |
| 472 | // continue |
| 473 | } |
| 474 | |
| 475 | // Maintain a target number of items to compact per iteration. Break the list iteration when the target is reached |
| 476 | targetEvictCount := cacheSize - c.compactLowWatermark |
| 477 | if targetEvictCount <= 0 { |
| 478 | base.InfofCtx(ctx, base.KeyCache, "Stopping channel cache compaction, size %d", cacheSize) |
| 479 | return |
| 480 | } |
| 481 | base.TracefCtx(ctx, base.KeyCache, "Target eviction count: %d (lwm:%d)", targetEvictCount, c.compactLowWatermark) |
| 482 | |
| 483 | // Iterates through cache entries based on cache size at start of compaction iteration loop. Intentionally |
| 484 | // ignores channels added during compaction iteration |
| 485 | inactiveEvictionCandidates := make([]*channels.AppendOnlyListElement, 0) |
| 486 | nruEvictionCandidates := make([]*channels.AppendOnlyListElement, 0) |
| 487 | |
| 488 | // channelCacheList is an append only list. Iterator iterates over the current list at the time the iterator was created. |
| 489 | // Ensures that there are no data races with goroutines appending to the list. |
| 490 | var elementCount int |
| 491 | compactCallback := func(elem *channels.AppendOnlyListElement) bool { |
| 492 | elementCount++ |
| 493 | singleChannelCache, ok := elem.Value.(*singleChannelCacheImpl) |
| 494 | if !ok { |
| 495 | base.WarnfCtx(ctx, "Non-cache entry (%T) found in channel cache during compaction - ignoring", elem.Value) |
| 496 | return true |
| 497 | } |
| 498 | |
| 499 | // If channel marked as recently used, update recently used flag and continue |
| 500 | if singleChannelCache.recentlyUsed.IsTrue() { |
| 501 | singleChannelCache.recentlyUsed.Set(false) |
| 502 | return true |
| 503 | } |
| 504 | |
| 505 | // Determine whether NRU channel is active, to establish eviction priority |
| 506 | isActive := c.activeChannels.IsActive(singleChannelCache.channelID) |
| 507 | if !isActive { |
| 508 | base.TracefCtx(ctx, base.KeyCache, "Marking inactive cache entry %q for eviction ", base.UD(singleChannelCache.channelID)) |
| 509 | inactiveEvictionCandidates = append(inactiveEvictionCandidates, elem) |
| 510 | } else { |
| 511 | base.TracefCtx(ctx, base.KeyCache, "Marking NRU cache entry %q for eviction", base.UD(singleChannelCache.channelID)) |
| 512 | nruEvictionCandidates = append(nruEvictionCandidates, elem) |
no test coverage detected