From b8219a9011c55c9532d3807588c8f3158fa20441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Wed, 12 Jun 2024 15:34:39 +0200 Subject: [PATCH] routing/http: fix goroutine/memory leak I've noticed some memory and goroutine buildup, linked to that function. It seems like when the context get cancelled, the consumer could be gone, but that function would still attempt to write in the channel and block forever. --- routing/http/contentrouter/contentrouter.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/routing/http/contentrouter/contentrouter.go b/routing/http/contentrouter/contentrouter.go index 9115ef154..1e4b2a8ec 100644 --- a/routing/http/contentrouter/contentrouter.go +++ b/routing/http/contentrouter/contentrouter.go @@ -113,7 +113,7 @@ func (c *contentRouter) Ready() bool { // readProviderResponses reads peer records (and bitswap records for legacy // compatibility) from the iterator into the given channel. -func readProviderResponses(iter iter.ResultIter[types.Record], ch chan<- peer.AddrInfo) { +func readProviderResponses(ctx context.Context, iter iter.ResultIter[types.Record], ch chan<- peer.AddrInfo) { defer close(ch) defer iter.Close() for iter.Next() { @@ -140,10 +140,14 @@ func readProviderResponses(iter iter.ResultIter[types.Record], ch chan<- peer.Ad addrs = append(addrs, a.Multiaddr) } - ch <- peer.AddrInfo{ + select { + case <-ctx.Done(): + return + case ch <- peer.AddrInfo{ ID: *result.ID, - Addrs: addrs, + Addrs: addrs}: } + //lint:ignore SA1019 // ignore staticcheck case types.SchemaBitswap: //lint:ignore SA1019 // ignore staticcheck @@ -162,9 +166,12 @@ func readProviderResponses(iter iter.ResultIter[types.Record], ch chan<- peer.Ad addrs = append(addrs, a.Multiaddr) } - ch <- peer.AddrInfo{ + select { + case <-ctx.Done(): + return + case ch <- peer.AddrInfo{ ID: *result.ID, - Addrs: addrs, + Addrs: addrs}: } } } @@ -179,7 +186,7 @@ func (c *contentRouter) FindProvidersAsync(ctx context.Context, key cid.Cid, num return ch } ch := make(chan peer.AddrInfo) - go readProviderResponses(resultsIter, ch) + go readProviderResponses(ctx, resultsIter, ch) return ch }