[management] shift network map data store onto the read replica (#8302)

This commit is contained in:
Pascal Fischer
2026-10-25 22:34:44 +01:00
committed by GitHub
parent dd38fabc82
commit fdc51d6f95
22 changed files with 1095 additions and 47 deletions
@@ -26,6 +26,9 @@ type Buffer[T any] struct {
mu sync.Mutex
waiting map[string][]chan result[T]
// inFlight holds the keys with a running fetch and whether their next flush
// is due once it ends. It is nil unless fetches are serialized.
inFlight map[string]bool
}
type result[T any] struct {
@@ -45,6 +48,15 @@ func New[T any](ctx context.Context, name string, interval time.Duration, fetch
}
}
// NewSerialized returns a Buffer like New that runs at most one fetch per key at
// a time. Requests arriving during a fetch form the next batch, which is fetched
// once both its window closed and the running fetch ended.
func NewSerialized[T any](ctx context.Context, name string, interval time.Duration, fetch FetchFunc[T]) *Buffer[T] {
b := New(ctx, name, interval, fetch)
b.inFlight = make(map[string]bool)
return b
}
// Get returns the value for key, sharing one fetch with the other callers of
// the current batch. The value is shared as is, so callers must treat it as
// read-only unless the fetch hands out copies.
@@ -71,8 +83,16 @@ func (b *Buffer[T]) Get(ctx context.Context, key string) (T, error) {
func (b *Buffer[T]) flush(key string) {
b.mu.Lock()
if _, running := b.inFlight[key]; running {
b.inFlight[key] = true
b.mu.Unlock()
return
}
waiting := b.waiting[key]
delete(b.waiting, key)
if b.inFlight != nil && len(waiting) > 0 {
b.inFlight[key] = false
}
b.mu.Unlock()
if len(waiting) == 0 {
@@ -86,6 +106,17 @@ func (b *Buffer[T]) flush(key string) {
for _, ch := range waiting {
ch <- result[T]{value: value, err: err}
}
if b.inFlight == nil {
return
}
b.mu.Lock()
due := b.inFlight[key]
delete(b.inFlight, key)
b.mu.Unlock()
if due {
go b.flush(key)
}
}
// Interval reads a buffer interval from envVar, falling back to def.