From a413681253a37ae451bfc4b518df456b064d687e Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 2 Dec 2021 19:29:44 +0100 Subject: [PATCH] Cancel pending commands on downstream disconnect If a client queues a high number of commands and then disconnects, remove all of the pending commands. This avoids unnecessarily sending commands whose results won't be used. --- upstream.go | 12 ++++++++++++ user.go | 1 + 2 files changed, 13 insertions(+) diff --git a/upstream.go b/upstream.go index db42827..87e41fe 100644 --- a/upstream.go +++ b/upstream.go @@ -385,6 +385,18 @@ func (uc *upstreamConn) dequeueCommand(cmd string) (*downstreamConn, *irc.Messag return dc, msg } +func (uc *upstreamConn) cancelPendingCommandsByDownstreamID(downstreamID uint64) { + for cmd := range uc.pendingCmds { + // We can't cancel the currently running command stored in + // uc.pendingCmds[cmd][0] + for i := len(uc.pendingCmds[cmd]) - 1; i >= 1; i-- { + if uc.pendingCmds[cmd][i].downstreamID == downstreamID { + uc.pendingCmds[cmd] = append(uc.pendingCmds[cmd][:i], uc.pendingCmds[cmd][i+1:]...) + } + } + } +} + func (uc *upstreamConn) parseMembershipPrefix(s string) (ms *memberships, nick string) { memberships := make(memberships, 0, 4) i := 0 diff --git a/user.go b/user.go index 672381e..2d447d7 100644 --- a/user.go +++ b/user.go @@ -662,6 +662,7 @@ func (u *user) run() { }) u.forEachUpstream(func(uc *upstreamConn) { + uc.cancelPendingCommandsByDownstreamID(dc.id) uc.updateAway() uc.updateMonitor() })