You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In our control-plane implementation, we are seeing a significant memory leak in specific cases.
Taking a closer look the memory leak can be attributed with a goroutine leak.
Looking at profiles we see that we have far too many goroutines from the DeltaStreamHandler method
(significantly more than active streams).
This is currently occurring when using the delta protocol with ads from an envoy client,
targeting a snapshot cache.
The following goroutine has the potential to leak when s.processDelta returns with an error.
Here is an example of how the goroutine leaks.
Two or more requests are made on the same stream (as in the case when using ADS)
The goroutine for-loop gets past and is blocked on the request being sent on the (unbuffered) channel.
While processing the first request, an error is returned (e.g. from a callback) and the processDelta method is exited, stopping any processing of the request channel. For example you could return an error here.
The goroutine is still blocked on the channel sending. here. Because processDelta has returned, there will not be a read from reqCh and the goroutine ends up leaking.
A possible fix would be the following
for {
req, err := str.Recv()
if err != nil {
close(reqCh)
return
}
select {
case reqCh <- req:
case <-str.Context().Done():
close(reqCh)
return
}
}
this relies on the fact if processDelta does return an error it implies that the stream would be closed, and so we can rely on str.Context().Done() to run in this scenario.
This is similar to what is implemented for the STOW stream handler. (We could also use this implementation instead)
go func() {
defer close(reqCh)
for {
req, err := stream.Recv()
if err != nil {
return
}
select {
case reqCh <- req:
case <-stream.Context().Done():
return
case <-s.ctx.Done():
return
}
}
}()
The text was updated successfully, but these errors were encountered:
go-control-plane version: 2259f26
In our control-plane implementation, we are seeing a significant memory leak in specific cases.
Taking a closer look the memory leak can be attributed with a goroutine leak.
Looking at profiles we see that we have far too many goroutines from the DeltaStreamHandler method
(significantly more than active streams).
This is currently occurring when using the delta protocol with ads from an envoy client,
targeting a snapshot cache.
The following goroutine has the potential to leak when
s.processDelta
returns with an error.Here is an example of how the goroutine leaks.
reqCh
and read from the channelhere.
reqCh
and the goroutine ends up leaking.A possible fix would be the following
this relies on the fact if processDelta does return an error it implies that the stream would be closed, and so we can rely on
str.Context().Done()
to run in this scenario.This is similar to what is implemented for the STOW stream handler. (We could also use this implementation instead)
The text was updated successfully, but these errors were encountered: