From 017c51c246179321f0857e6ebe566d6d66ef6c94 Mon Sep 17 00:00:00 2001 From: byigorv <60062354+byigorv@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:52:37 +0300 Subject: [PATCH] fix mem leak in hubConnectionIndex (#22560) --- server/channels/app/platform/web_hub.go | 2 ++ server/channels/app/platform/web_hub_test.go | 37 ++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/server/channels/app/platform/web_hub.go b/server/channels/app/platform/web_hub.go index d37f3d4762..02652adf58 100644 --- a/server/channels/app/platform/web_hub.go +++ b/server/channels/app/platform/web_hub.go @@ -599,6 +599,8 @@ func (i *hubConnectionIndex) Remove(wc *WebConn) { last := userConnections[len(userConnections)-1] // set the slot that we are trying to remove to be the last connection. userConnections[userConnIndex] = last + // remove the last connection pointer from slice. + userConnections[len(userConnections)-1] = nil // remove the last connection from the slice. i.byUserId[wc.UserId] = userConnections[:len(userConnections)-1] // set the index of the connection that was moved to the new index. diff --git a/server/channels/app/platform/web_hub_test.go b/server/channels/app/platform/web_hub_test.go index 10db2fcb7c..0fc45e730c 100644 --- a/server/channels/app/platform/web_hub_test.go +++ b/server/channels/app/platform/web_hub_test.go @@ -8,6 +8,7 @@ import ( "net" "net/http" "net/http/httptest" + "runtime" "testing" "time" @@ -539,6 +540,42 @@ func BenchmarkHubConnIndex(b *testing.B) { }) } +func TestHubConnIndexRemoveMemLeak(t *testing.T) { + th := Setup(t) + defer th.TearDown() + + connIndex := newHubConnectionIndex(1 * time.Second) + + wc := &WebConn{ + Platform: th.Service, + Suite: th.Suite, + } + wc.SetConnectionID(model.NewId()) + wc.SetSession(&model.Session{}) + + ch := make(chan struct{}) + + runtime.SetFinalizer(wc, func(*WebConn) { + close(ch) + }) + + connIndex.Add(wc) + connIndex.Remove(wc) + + runtime.GC() + + timer := time.NewTimer(3 * time.Second) + defer timer.Stop() + + select { + case <-ch: + case <-timer.C: + require.Fail(t, "timeout waiting for collection of wc") + } + + assert.Len(t, connIndex.byConnection, 0) +} + var hubSink *Hub func BenchmarkGetHubForUserId(b *testing.B) {