[#169] pool: Close inner pools during close routine
All checks were successful
DCO / DCO (pull_request) Successful in 1m9s
Tests and linters / Lint (pull_request) Successful in 1m26s
Tests and linters / Tests (1.20) (pull_request) Successful in 1m27s
Tests and linters / Tests (1.19) (pull_request) Successful in 1m44s

Some apps do not reuse pool instance and expect that
`pool.Close()` free resources. But it didn't actually
close inner SDK clients, so it leads to goroutine leak
in storage.

Signed-off-by: Alex Vanin <a.vanin@yadro.com>
This commit is contained in:
Alexey Vanin 2023-09-20 12:14:37 +03:00
parent 555ccc63b2
commit 99c273f499
2 changed files with 20 additions and 0 deletions

View file

@ -189,3 +189,7 @@ func (m *mockClient) restartIfUnhealthy(ctx context.Context) (healthy bool, chan
} }
return return
} }
func (m *mockClient) close() error {
return nil
}

View file

@ -78,6 +78,8 @@ type client interface {
dial(ctx context.Context) error dial(ctx context.Context) error
// see clientWrapper.restartIfUnhealthy. // see clientWrapper.restartIfUnhealthy.
restartIfUnhealthy(ctx context.Context) (bool, bool) restartIfUnhealthy(ctx context.Context) (bool, bool)
// see clientWrapper.close.
close() error
} }
// clientStatus provide access to some metrics for connection. // clientStatus provide access to some metrics for connection.
@ -1080,6 +1082,13 @@ func (c *clientWrapper) incRequests(elapsed time.Duration, method MethodIndex) {
} }
} }
func (c *clientWrapper) close() error {
if c.client != nil {
return c.client.Close()
}
return nil
}
func (c *clientStatusMonitor) handleError(ctx context.Context, st apistatus.Status, err error) error { func (c *clientStatusMonitor) handleError(ctx context.Context, st apistatus.Status, err error) error {
if err != nil { if err != nil {
if needCountError(ctx, err) { if needCountError(ctx, err) {
@ -2766,6 +2775,13 @@ func (p *Pool) NetworkInfo(ctx context.Context) (netmap.NetworkInfo, error) {
func (p *Pool) Close() { func (p *Pool) Close() {
p.cancel() p.cancel()
<-p.closedCh <-p.closedCh
// close all clients
for _, pools := range p.innerPools {
for _, cli := range pools.clients {
_ = cli.close()
}
}
} }
// SyncContainerWithNetwork applies network configuration received via // SyncContainerWithNetwork applies network configuration received via