diff --git a/cmd/routedns/config.go b/cmd/routedns/config.go index 3c8736e..763e59c 100644 --- a/cmd/routedns/config.go +++ b/cmd/routedns/config.go @@ -194,6 +194,7 @@ type group struct { // Prefetch options PrefetchWindow time.Duration `toml:"prefetch-window"` // Time period to track queries for prefetching, default 1h PrefetchThreshold uint64 `toml:"prefetch-threshold"` // Minimum number of queries per window to enable prefetching, default 5 + PrefetchCacheSize int `toml:"prefetch-cache-size"` // Maximum number of items to cache PrefetchMaxItems int `toml:"prefetch-max-items"` // Maximum number of items to track prefetch, default (0) unlimited } diff --git a/cmd/routedns/example-config/prefetch.toml b/cmd/routedns/example-config/prefetch.toml index 2f20107..477128c 100644 --- a/cmd/routedns/example-config/prefetch.toml +++ b/cmd/routedns/example-config/prefetch.toml @@ -10,8 +10,9 @@ resolvers = ["cloudflare-dot"] type = "prefetch" resolvers = ["cloudflare-cached"] prefetch-window = "15m" # Minimum time between queries to remain eligible for prefetch -prefetch-threshold = 3 # Min number of queries to enable prefetch -prefetch-max-items = 100 # Max number of items to track for prefetch +prefetch-threshold = 3 # Min number of queries required to enable prefetch +prefetch-cache-size = 150 # Max number of queries to track for prefetch +prefetch-max-items = 50 # Max number of items to prefetch [listeners.local-udp] address = "127.0.0.1:53" diff --git a/cmd/routedns/main.go b/cmd/routedns/main.go index 0a36c32..bbc7519 100644 --- a/cmd/routedns/main.go +++ b/cmd/routedns/main.go @@ -699,6 +699,7 @@ func instantiateGroup(id string, g group, resolvers map[string]rdns.Resolver) er opt := rdns.PrefetchOptions{ PrefetchWindow: g.PrefetchWindow, PrefetchThreshold: g.PrefetchThreshold, + PrefetchCacheSize: g.PrefetchCacheSize, PrefetchMaxItems: g.PrefetchMaxItems, } resolvers[id] = rdns.NewPrefetch(id, gr[0], opt) diff --git a/doc/configuration.md b/doc/configuration.md index 57892d6..24e0192 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -442,7 +442,7 @@ Example config files: [cache.toml](../cmd/routedns/example-config/cache.toml), [ ### Prefetch -While [Cache](#cache) has built-in prefetch capabilities, a the dedicated `prefetch` group may be more appropriate for some use cases. Its tracks the number of queries made and actively prefetches frequenty requested records. While it actively sends queries in order to refresh a cache, it does not cache responses itself and relies on a cache upstream from it. +While [Cache](#cache) has built-in prefetch capabilities, a the dedicated `prefetch` group may be more appropriate for some use cases. Its tracks the number of queries made within a time window and actively prefetches frequenty requested records. While it actively sends queries in order to refresh a cache, it does not cache responses itself and relies on a cache upstream from it. #### Configuration @@ -452,8 +452,9 @@ Options: - `resolvers` - Array of upstream resolvers, only one is supported. - `prefetch-window` - Minimum time between queries to remain eligible for prefetching. Supports time units `s`, `m`, and `h`. Default: 1h. -- `prefetch-threshold` - Minimum number of queries for a name to enable prefetch. Default: 5. -- `prefetch-max-items` - Maximum number of items to track for prefetch. Values that are too large can cause memory issues. Prefetch is disabled if 0 or not set. +- `prefetch-threshold` - Minimum number of queries required for a name to enable prefetch. Default: 5. +- `prefetch-cache-size` - Maximum number of queries to track for prefetch. Values that are too large can cause memory issues. Prefetch is disabled if 0. Default: `prefetch-max-items * 3`. +- `prefetch-max-items` - Maximum number of items to prefetch. Values that are too large can cause memory issues. Prefetch is disabled if 0 or not set. #### Examples @@ -469,7 +470,8 @@ type = "prefetch" resolvers = ["cloudflare-cached"] prefetch-window = "15m" prefetch-threshold = 3 -prefetch-max-items = 100 +prefetch-cache-size = 150 +prefetch-max-items = 50 ``` Example config files: [prefetch.toml](../cmd/routedns/example-config/prefetch.toml) diff --git a/prefetch.go b/prefetch.go index 353afd8..19d4e02 100644 --- a/prefetch.go +++ b/prefetch.go @@ -25,6 +25,7 @@ var _ Resolver = &RoundRobin{} type PrefetchOptions struct { PrefetchWindow time.Duration PrefetchThreshold uint64 + PrefetchCacheSize int PrefetchMaxItems int } @@ -35,6 +36,9 @@ func NewPrefetch(id string, resolver Resolver, opt PrefetchOptions) *Prefetch { if opt.PrefetchThreshold == 0 { opt.PrefetchThreshold = 5 } + if opt.PrefetchCacheSize == 0 { + opt.PrefetchCacheSize = opt.PrefetchMaxItems * 3 + } r := &Prefetch{ id: id, @@ -42,7 +46,7 @@ func NewPrefetch(id string, resolver Resolver, opt PrefetchOptions) *Prefetch { options: opt, } r.nameCache = expirationcache.NewCache[atomic.Uint64](context.Background(), expirationcache.Options{ - MaxSize: uint(opt.PrefetchMaxItems), + MaxSize: uint(opt.PrefetchCacheSize), }) r.queryCache = expirationcache.NewCacheWithOnExpired(context.Background(), expirationcache.Options{ MaxSize: uint(opt.PrefetchMaxItems),