From 740e3af681e9f6cabaddbbd9a910f1d4cd233408 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 21 Sep 2022 21:19:57 +0300 Subject: [PATCH] nfd-master: implement ratelimiter for nfd api updates Implement a naive ratelimiter for node update events originating from the nfd API. We might get a ton of events in short interval. The simplest example is startup when we get a separate Add event for every NodeFeature and NodeFeatureRule object. Without rate limiting we run "update all nodes" separately for each NodeFeatureRule object, plus, we would run "update node X" separately for each NodeFeature object targeting node X. This is a huge amount of wasted work because in principle just running "update all nodes" once should be enough. --- pkg/nfd-master/nfd-master.go | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/pkg/nfd-master/nfd-master.go b/pkg/nfd-master/nfd-master.go index 7d1bdac3e..75da6bd62 100644 --- a/pkg/nfd-master/nfd-master.go +++ b/pkg/nfd-master/nfd-master.go @@ -259,16 +259,34 @@ func (m *nfdMaster) runGrpcServer(errChan chan<- error) { // nfdAPIUpdateHandler handles events from the nfd API controller. func (m *nfdMaster) nfdAPIUpdateHandler() { + updateAll := false + updateNodes := make(map[string]struct{}) + rateLimit := time.After(time.Second) for { select { case <-m.nfdController.updateAllNodesChan: - if err := m.nfdAPIUpdateAllNodes(); err != nil { - klog.Error(err) - } + updateAll = true case nodeName := <-m.nfdController.updateOneNodeChan: - if err := m.nfdAPIUpdateOneNode(nodeName); err != nil { - klog.Error(err) + updateNodes[nodeName] = struct{}{} + case <-rateLimit: + // Check what we need to do + // TODO: we might want to update multiple nodes in parallel + if updateAll { + if err := m.nfdAPIUpdateAllNodes(); err != nil { + klog.Error(err) + } + } else { + for nodeName := range updateNodes { + if err := m.nfdAPIUpdateOneNode(nodeName); err != nil { + klog.Error(err) + } + } } + + // Reset "work queue" and timer + updateAll = false + updateNodes = make(map[string]struct{}) + rateLimit = time.After(time.Second) } } }