Skip to content

Commit

Permalink
try to fix akward behaviour on parallel http calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Cellebyte committed Apr 23, 2024
1 parent 310dd65 commit 877f59b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
2 changes: 2 additions & 0 deletions pkg/monitoring/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ type basicCollector struct {
logger logr.Logger
}

// only use with Lock called before
func (c *basicCollector) clearChannels() {
defer c.mu.Unlock()
c.channels = []chan<- prometheus.Metric{}
}
func (d *typedFactoryDesc) mustNewConstMetric(value float64, labels ...string) prometheus.Metric {
Expand Down
22 changes: 13 additions & 9 deletions pkg/monitoring/frr.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,18 +253,22 @@ func (c *frrCollector) Update(ch chan<- prometheus.Metric) error {
if len(c.channels) == 1 {
c.wg = sync.WaitGroup{}
c.wg.Add(1)
go func() {
defer c.wg.Done()
vrfs := c.getVrfs()
neighbors := c.getBGPNeighbors()
routes := c.getRoutes()
// Ensure all other function calls will wait
c.mu.Unlock()
routes, neighbors, vrfs := func() ([]route.Information, frr.BGPVrfSummary, []frr.VrfVniSpec) {
return c.getRoutes(), c.getBGPNeighbors(), c.getVrfs()
}()
go func(routes []route.Information, neighbors frr.BGPVrfSummary, vrfs []frr.VrfVniSpec) {
c.mu.Lock()
defer c.mu.Unlock()
// unlock is done after return using defer
defer c.wg.Done()
c.updateChannels(vrfs, routes, neighbors)
c.clearChannels()
}()
}(routes, neighbors, vrfs)
// unlock is done in this function.
defer c.clearChannels()
} else {
c.mu.Unlock()
}
c.mu.Unlock()
c.wg.Wait()
return nil
}
21 changes: 13 additions & 8 deletions pkg/monitoring/nl.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,22 @@ func (c *netlinkCollector) Update(ch chan<- prometheus.Metric) error {
if len(c.channels) == 1 {
c.wg = sync.WaitGroup{}
c.wg.Add(1)
go func() {
defer c.wg.Done()
routes := c.getRoutes()
neighbors := c.getNeighbors()
// Ensure all other function calls will wait
c.mu.Unlock()
routes, neighbors := func() ([]route.Information, []nl.NeighborInformation) {
return c.getRoutes(), c.getNeighbors()
}()
go func(routes []route.Information, neighbors []nl.NeighborInformation) {
c.mu.Lock()
defer c.mu.Unlock()
// unlock is done after return using defer
defer c.wg.Done()
c.updateChannels(neighbors, routes)
c.clearChannels()
}()
}(routes, neighbors)
// unlock is done in this function.
defer c.clearChannels()
} else {
c.mu.Unlock()
}
c.mu.Unlock()
c.wg.Wait()
return nil
}

0 comments on commit 877f59b

Please sign in to comment.