Remove the relay's broker wait channel after each tick (closes #151)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
The IRC relay registers a broker wait channel on each pass of its loop, and when the 100 ms ticker fired instead of a notification it looped without removing that channel. An idle IRC listener connection added ten channels a second to the broker, and all but the last stayed after the connection closed. The ticker case now removes its channel, as the HTTP long-poll does after its timer. Broker.ListenerCount returns how many wait channels a user holds, so the test can check that an idle connection holds at most one, and none after it closes. Model: opus-5-5
This commit is contained in:
@@ -5,6 +5,9 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"sneak.berlin/go/neoirc/internal/ircserver"
|
||||
)
|
||||
|
||||
// queueMessage queues a message for the user with nick
|
||||
@@ -44,6 +47,51 @@ func (env *testEnv) queueMessage(
|
||||
env.brk.Notify(sessionID)
|
||||
}
|
||||
|
||||
// TestRelayKeepsOneWaitChannel checks that an idle IRC
|
||||
// listener connection holds at most one broker wait channel
|
||||
// across several relay ticks, and none once it closes.
|
||||
func TestRelayKeepsOneWaitChannel(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const idleTicks = 5
|
||||
|
||||
env := newTestEnv(t)
|
||||
|
||||
client := env.dial(t)
|
||||
client.register("idle")
|
||||
|
||||
sessionID, err := env.database.GetSessionByNick(t.Context(), "idle")
|
||||
if err != nil {
|
||||
t.Fatalf("get session of idle: %v", err)
|
||||
}
|
||||
|
||||
for tick := range idleTicks {
|
||||
time.Sleep(ircserver.PollInterval)
|
||||
|
||||
got := env.brk.ListenerCount(sessionID)
|
||||
if got > 1 {
|
||||
t.Fatalf("tick %d: got %d wait channels, want at most 1",
|
||||
tick+1, got)
|
||||
}
|
||||
}
|
||||
|
||||
err = client.conn.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("close: %v", err)
|
||||
}
|
||||
|
||||
deadline := time.Now().Add(testTimeout)
|
||||
|
||||
for env.brk.ListenerCount(sessionID) != 0 {
|
||||
if time.Now().After(deadline) {
|
||||
t.Fatalf("after close: got %d wait channels, want 0",
|
||||
env.brk.ListenerCount(sessionID))
|
||||
}
|
||||
|
||||
time.Sleep(relayCheckStep)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRelayMultiLineBody checks that each line of a PRIVMSG
|
||||
// or NOTICE body sent over the HTTP API reaches an IRC
|
||||
// listener user as its own line.
|
||||
|
||||
Reference in New Issue
Block a user