stop storing context received from outside

Signed-off-by: Luca Bigliardi <shammash@google.com>
This commit is contained in:
Luca Bigliardi 2021-03-27 12:35:38 +01:00
parent e8f5109703
commit 0ec08d5ea1
3 changed files with 61 additions and 49 deletions

41
irc.go
View File

@ -84,9 +84,6 @@ type IRCNotifier struct {
Client *irc.Conn Client *irc.Conn
AlertMsgs chan AlertMsg AlertMsgs chan AlertMsg
stopCtx context.Context
stopWg *sync.WaitGroup
// irc.Conn has a Connected() method that can tell us wether the TCP // irc.Conn has a Connected() method that can tell us wether the TCP
// connection is up, and thus if we should trigger connect/disconnect. // connection is up, and thus if we should trigger connect/disconnect.
// We need to track the session establishment also at a higher level to // We need to track the session establishment also at a higher level to
@ -104,7 +101,7 @@ type IRCNotifier struct {
BackoffCounter Delayer BackoffCounter Delayer
} }
func NewIRCNotifier(stopCtx context.Context, stopWg *sync.WaitGroup, config *Config, alertMsgs chan AlertMsg, delayerMaker DelayerMaker) (*IRCNotifier, error) { func NewIRCNotifier(config *Config, alertMsgs chan AlertMsg, delayerMaker DelayerMaker) (*IRCNotifier, error) {
ircConfig := makeGOIRCConfig(config) ircConfig := makeGOIRCConfig(config)
@ -121,8 +118,6 @@ func NewIRCNotifier(stopCtx context.Context, stopWg *sync.WaitGroup, config *Con
NickPassword: config.IRCNickPass, NickPassword: config.IRCNickPass,
Client: client, Client: client,
AlertMsgs: alertMsgs, AlertMsgs: alertMsgs,
stopCtx: stopCtx,
stopWg: stopWg,
sessionUpSignal: make(chan bool), sessionUpSignal: make(chan bool),
sessionDownSignal: make(chan bool), sessionDownSignal: make(chan bool),
channelReconciler: channelReconciler, channelReconciler: channelReconciler,
@ -177,7 +172,7 @@ func (n *IRCNotifier) MaybeIdentifyNick() {
time.Sleep(n.NickservDelayWait) time.Sleep(n.NickservDelayWait)
} }
func (n *IRCNotifier) ChannelJoined(channel string) bool { func (n *IRCNotifier) ChannelJoined(ctx context.Context, channel string) bool {
isJoined, waitJoined := n.channelReconciler.JoinChannel(channel) isJoined, waitJoined := n.channelReconciler.JoinChannel(channel)
if isJoined { if isJoined {
@ -190,19 +185,19 @@ func (n *IRCNotifier) ChannelJoined(channel string) bool {
case <-time.After(ircJoinWaitSecs * time.Second): case <-time.After(ircJoinWaitSecs * time.Second):
log.Printf("Channel %s not joined after %d seconds, giving bad news to caller", channel, ircJoinWaitSecs) log.Printf("Channel %s not joined after %d seconds, giving bad news to caller", channel, ircJoinWaitSecs)
return false return false
case <-n.stopCtx.Done(): case <-ctx.Done():
log.Printf("Context canceled while waiting for join on channel %s", channel) log.Printf("Context canceled while waiting for join on channel %s", channel)
return false return false
} }
} }
func (n *IRCNotifier) SendAlertMsg(alertMsg *AlertMsg) { func (n *IRCNotifier) SendAlertMsg(ctx context.Context, alertMsg *AlertMsg) {
if !n.sessionUp { if !n.sessionUp {
log.Printf("Cannot send alert to %s : IRC not connected", alertMsg.Channel) log.Printf("Cannot send alert to %s : IRC not connected", alertMsg.Channel)
ircSendMsgErrors.WithLabelValues(alertMsg.Channel, "not_connected").Inc() ircSendMsgErrors.WithLabelValues(alertMsg.Channel, "not_connected").Inc()
return return
} }
if !n.ChannelJoined(alertMsg.Channel) { if !n.ChannelJoined(ctx, alertMsg.Channel) {
log.Printf("Cannot send alert to %s : cannot join channel", alertMsg.Channel) log.Printf("Cannot send alert to %s : cannot join channel", alertMsg.Channel)
ircSendMsgErrors.WithLabelValues(alertMsg.Channel, "not_joined").Inc() ircSendMsgErrors.WithLabelValues(alertMsg.Channel, "not_joined").Inc()
return return
@ -232,27 +227,27 @@ func (n *IRCNotifier) ShutdownPhase() {
} }
} }
func (n *IRCNotifier) ConnectedPhase() { func (n *IRCNotifier) ConnectedPhase(ctx context.Context) {
select { select {
case alertMsg := <-n.AlertMsgs: case alertMsg := <-n.AlertMsgs:
n.SendAlertMsg(&alertMsg) n.SendAlertMsg(ctx, &alertMsg)
case <-n.sessionDownSignal: case <-n.sessionDownSignal:
n.sessionUp = false n.sessionUp = false
n.channelReconciler.Stop() n.channelReconciler.Stop()
n.Client.Quit("see ya") n.Client.Quit("see ya")
ircConnectedGauge.Set(0) ircConnectedGauge.Set(0)
case <-n.stopCtx.Done(): case <-ctx.Done():
log.Printf("IRC routine asked to terminate") log.Printf("IRC routine asked to terminate")
} }
} }
func (n *IRCNotifier) SetupPhase() { func (n *IRCNotifier) SetupPhase(ctx context.Context) {
if !n.Client.Connected() { if !n.Client.Connected() {
log.Printf("Connecting to IRC %s", n.Client.Config().Server) log.Printf("Connecting to IRC %s", n.Client.Config().Server)
if ok := n.BackoffCounter.DelayContext(n.stopCtx); !ok { if ok := n.BackoffCounter.DelayContext(ctx); !ok {
return return
} }
if err := n.Client.ConnectContext(n.stopCtx); err != nil { if err := n.Client.ConnectContext(ctx); err != nil {
log.Printf("Could not connect to IRC: %s", err) log.Printf("Could not connect to IRC: %s", err)
return return
} }
@ -262,23 +257,23 @@ func (n *IRCNotifier) SetupPhase() {
case <-n.sessionUpSignal: case <-n.sessionUpSignal:
n.sessionUp = true n.sessionUp = true
n.MaybeIdentifyNick() n.MaybeIdentifyNick()
n.channelReconciler.Start(n.stopCtx) n.channelReconciler.Start(ctx)
ircConnectedGauge.Set(1) ircConnectedGauge.Set(1)
case <-n.sessionDownSignal: case <-n.sessionDownSignal:
log.Printf("Receiving a session down before the session is up, this is odd") log.Printf("Receiving a session down before the session is up, this is odd")
case <-n.stopCtx.Done(): case <-ctx.Done():
log.Printf("IRC routine asked to terminate") log.Printf("IRC routine asked to terminate")
} }
} }
func (n *IRCNotifier) Run() { func (n *IRCNotifier) Run(ctx context.Context, stopWg *sync.WaitGroup) {
defer n.stopWg.Done() defer stopWg.Done()
for n.stopCtx.Err() != context.Canceled { for ctx.Err() != context.Canceled {
if !n.sessionUp { if !n.sessionUp {
n.SetupPhase() n.SetupPhase(ctx)
} else { } else {
n.ConnectedPhase() n.ConnectedPhase(ctx)
} }
} }
n.ShutdownPhase() n.ShutdownPhase()

View File

@ -42,26 +42,26 @@ func makeTestIRCConfig(IRCPort int) *Config {
} }
} }
func makeTestNotifier(t *testing.T, config *Config) (*IRCNotifier, chan AlertMsg, context.CancelFunc, *sync.WaitGroup) { func makeTestNotifier(t *testing.T, config *Config) (*IRCNotifier, chan AlertMsg, context.Context, context.CancelFunc, *sync.WaitGroup) {
fakeDelayerMaker := &FakeDelayerMaker{} fakeDelayerMaker := &FakeDelayerMaker{}
alertMsgs := make(chan AlertMsg) alertMsgs := make(chan AlertMsg)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
stopWg := sync.WaitGroup{} stopWg := sync.WaitGroup{}
stopWg.Add(1) stopWg.Add(1)
notifier, err := NewIRCNotifier(ctx, &stopWg, config, alertMsgs, fakeDelayerMaker) notifier, err := NewIRCNotifier(config, alertMsgs, fakeDelayerMaker)
if err != nil { if err != nil {
t.Fatal(fmt.Sprintf("Could not create IRC notifier: %s", err)) t.Fatal(fmt.Sprintf("Could not create IRC notifier: %s", err))
} }
notifier.Client.Config().Flood = true notifier.Client.Config().Flood = true
return notifier, alertMsgs, cancel, &stopWg return notifier, alertMsgs, ctx, cancel, &stopWg
} }
func TestServerPassword(t *testing.T) { func TestServerPassword(t *testing.T) {
server, port := makeTestServer(t) server, port := makeTestServer(t)
config := makeTestIRCConfig(port) config := makeTestIRCConfig(port)
config.IRCHostPass = "hostsecret" config.IRCHostPass = "hostsecret"
notifier, _, cancel, _ := makeTestNotifier(t, config) notifier, _, ctx, cancel, stopWg := makeTestNotifier(t, config)
var testStep sync.WaitGroup var testStep sync.WaitGroup
@ -72,11 +72,13 @@ func TestServerPassword(t *testing.T) {
server.SetHandler("JOIN", joinHandler) server.SetHandler("JOIN", joinHandler)
testStep.Add(1) testStep.Add(1)
go notifier.Run() go notifier.Run(ctx, stopWg)
testStep.Wait() testStep.Wait()
cancel() cancel()
stopWg.Wait()
server.Stop() server.Stop()
expectedCommands := []string{ expectedCommands := []string{
@ -95,7 +97,7 @@ func TestServerPassword(t *testing.T) {
func TestSendAlertOnPreJoinedChannel(t *testing.T) { func TestSendAlertOnPreJoinedChannel(t *testing.T) {
server, port := makeTestServer(t) server, port := makeTestServer(t)
config := makeTestIRCConfig(port) config := makeTestIRCConfig(port)
notifier, alertMsgs, cancel, _ := makeTestNotifier(t, config) notifier, alertMsgs, ctx, cancel, stopWg := makeTestNotifier(t, config)
var testStep sync.WaitGroup var testStep sync.WaitGroup
@ -113,7 +115,7 @@ func TestSendAlertOnPreJoinedChannel(t *testing.T) {
server.SetHandler("JOIN", joinedHandler) server.SetHandler("JOIN", joinedHandler)
testStep.Add(1) testStep.Add(1)
go notifier.Run() go notifier.Run(ctx, stopWg)
testStep.Wait() testStep.Wait()
@ -131,6 +133,8 @@ func TestSendAlertOnPreJoinedChannel(t *testing.T) {
testStep.Wait() testStep.Wait()
cancel() cancel()
stopWg.Wait()
server.Stop() server.Stop()
expectedCommands := []string{ expectedCommands := []string{
@ -150,7 +154,7 @@ func TestUsePrivmsgToSendAlertOnPreJoinedChannel(t *testing.T) {
server, port := makeTestServer(t) server, port := makeTestServer(t)
config := makeTestIRCConfig(port) config := makeTestIRCConfig(port)
config.UsePrivmsg = true config.UsePrivmsg = true
notifier, alertMsgs, cancel, _ := makeTestNotifier(t, config) notifier, alertMsgs, ctx, cancel, stopWg := makeTestNotifier(t, config)
var testStep sync.WaitGroup var testStep sync.WaitGroup
@ -168,7 +172,7 @@ func TestUsePrivmsgToSendAlertOnPreJoinedChannel(t *testing.T) {
server.SetHandler("JOIN", joinedHandler) server.SetHandler("JOIN", joinedHandler)
testStep.Add(1) testStep.Add(1)
go notifier.Run() go notifier.Run(ctx, stopWg)
testStep.Wait() testStep.Wait()
@ -186,6 +190,8 @@ func TestUsePrivmsgToSendAlertOnPreJoinedChannel(t *testing.T) {
testStep.Wait() testStep.Wait()
cancel() cancel()
stopWg.Wait()
server.Stop() server.Stop()
expectedCommands := []string{ expectedCommands := []string{
@ -204,7 +210,7 @@ func TestUsePrivmsgToSendAlertOnPreJoinedChannel(t *testing.T) {
func TestSendAlertAndJoinChannel(t *testing.T) { func TestSendAlertAndJoinChannel(t *testing.T) {
server, port := makeTestServer(t) server, port := makeTestServer(t)
config := makeTestIRCConfig(port) config := makeTestIRCConfig(port)
notifier, alertMsgs, cancel, _ := makeTestNotifier(t, config) notifier, alertMsgs, ctx, cancel, stopWg := makeTestNotifier(t, config)
var testStep sync.WaitGroup var testStep sync.WaitGroup
@ -220,7 +226,7 @@ func TestSendAlertAndJoinChannel(t *testing.T) {
server.SetHandler("JOIN", joinHandler) server.SetHandler("JOIN", joinHandler)
testStep.Add(1) testStep.Add(1)
go notifier.Run() go notifier.Run(ctx, stopWg)
testStep.Wait() testStep.Wait()
@ -238,6 +244,8 @@ func TestSendAlertAndJoinChannel(t *testing.T) {
testStep.Wait() testStep.Wait()
cancel() cancel()
stopWg.Wait()
server.Stop() server.Stop()
expectedCommands := []string{ expectedCommands := []string{
@ -258,7 +266,7 @@ func TestSendAlertAndJoinChannel(t *testing.T) {
func TestSendAlertDisconnected(t *testing.T) { func TestSendAlertDisconnected(t *testing.T) {
server, port := makeTestServer(t) server, port := makeTestServer(t)
config := makeTestIRCConfig(port) config := makeTestIRCConfig(port)
notifier, alertMsgs, cancel, _ := makeTestNotifier(t, config) notifier, alertMsgs, ctx, cancel, stopWg := makeTestNotifier(t, config)
var testStep, holdUserStep sync.WaitGroup var testStep, holdUserStep sync.WaitGroup
@ -278,7 +286,7 @@ func TestSendAlertDisconnected(t *testing.T) {
} }
server.SetHandler("USER", holdUser) server.SetHandler("USER", holdUser)
go notifier.Run() go notifier.Run(ctx, stopWg)
// Alert channels is not consumed while disconnected // Alert channels is not consumed while disconnected
select { select {
@ -314,6 +322,8 @@ func TestSendAlertDisconnected(t *testing.T) {
testStep.Wait() testStep.Wait()
cancel() cancel()
stopWg.Wait()
server.Stop() server.Stop()
expectedCommands := []string{ expectedCommands := []string{
@ -333,7 +343,7 @@ func TestSendAlertDisconnected(t *testing.T) {
func TestReconnect(t *testing.T) { func TestReconnect(t *testing.T) {
server, port := makeTestServer(t) server, port := makeTestServer(t)
config := makeTestIRCConfig(port) config := makeTestIRCConfig(port)
notifier, _, cancel, _ := makeTestNotifier(t, config) notifier, _, ctx, cancel, stopWg := makeTestNotifier(t, config)
var testStep sync.WaitGroup var testStep sync.WaitGroup
@ -344,7 +354,7 @@ func TestReconnect(t *testing.T) {
server.SetHandler("JOIN", joinHandler) server.SetHandler("JOIN", joinHandler)
testStep.Add(1) testStep.Add(1)
go notifier.Run() go notifier.Run(ctx, stopWg)
// Wait until the pre-joined channel is seen. // Wait until the pre-joined channel is seen.
testStep.Wait() testStep.Wait()
@ -357,6 +367,8 @@ func TestReconnect(t *testing.T) {
testStep.Wait() testStep.Wait()
cancel() cancel()
stopWg.Wait()
server.Stop() server.Stop()
expectedCommands := []string{ expectedCommands := []string{
@ -382,7 +394,7 @@ func TestConnectErrorRetry(t *testing.T) {
// Attempt SSL handshake. The server does not support it, resulting in // Attempt SSL handshake. The server does not support it, resulting in
// a connection error. // a connection error.
config.IRCUseSSL = true config.IRCUseSSL = true
notifier, _, cancel, _ := makeTestNotifier(t, config) notifier, _, ctx, cancel, stopWg := makeTestNotifier(t, config)
// Pilot reconnect attempts via backoff delay to prevent race // Pilot reconnect attempts via backoff delay to prevent race
// conditions in the test while we change the components behavior on // conditions in the test while we change the components behavior on
// the fly. // the fly.
@ -398,7 +410,7 @@ func TestConnectErrorRetry(t *testing.T) {
server.SetCloseEarly(earlyHandler) server.SetCloseEarly(earlyHandler)
go notifier.Run() go notifier.Run(ctx, stopWg)
delayer.StopDelay <- true delayer.StopDelay <- true
@ -419,6 +431,8 @@ func TestConnectErrorRetry(t *testing.T) {
joinStep.Wait() joinStep.Wait()
cancel() cancel()
stopWg.Wait()
server.Stop() server.Stop()
expectedCommands := []string{ expectedCommands := []string{
@ -437,7 +451,7 @@ func TestIdentify(t *testing.T) {
server, port := makeTestServer(t) server, port := makeTestServer(t)
config := makeTestIRCConfig(port) config := makeTestIRCConfig(port)
config.IRCNickPass = "nickpassword" config.IRCNickPass = "nickpassword"
notifier, _, cancel, _ := makeTestNotifier(t, config) notifier, _, ctx, cancel, stopWg := makeTestNotifier(t, config)
notifier.NickservDelayWait = 0 * time.Second notifier.NickservDelayWait = 0 * time.Second
var testStep sync.WaitGroup var testStep sync.WaitGroup
@ -451,11 +465,13 @@ func TestIdentify(t *testing.T) {
server.SetHandler("JOIN", joinHandler) server.SetHandler("JOIN", joinHandler)
testStep.Add(1) testStep.Add(1)
go notifier.Run() go notifier.Run(ctx, stopWg)
testStep.Wait() testStep.Wait()
cancel() cancel()
stopWg.Wait()
server.Stop() server.Stop()
expectedCommands := []string{ expectedCommands := []string{
@ -475,7 +491,7 @@ func TestGhostAndIdentify(t *testing.T) {
server, port := makeTestServer(t) server, port := makeTestServer(t)
config := makeTestIRCConfig(port) config := makeTestIRCConfig(port)
config.IRCNickPass = "nickpassword" config.IRCNickPass = "nickpassword"
notifier, _, cancel, _ := makeTestNotifier(t, config) notifier, _, ctx, cancel, stopWg := makeTestNotifier(t, config)
notifier.NickservDelayWait = 0 * time.Second notifier.NickservDelayWait = 0 * time.Second
var testStep, usedNick, unregisteredNickHandler sync.WaitGroup var testStep, usedNick, unregisteredNickHandler sync.WaitGroup
@ -503,7 +519,7 @@ func TestGhostAndIdentify(t *testing.T) {
server.SetHandler("JOIN", joinHandler) server.SetHandler("JOIN", joinHandler)
testStep.Add(1) testStep.Add(1)
go notifier.Run() go notifier.Run(ctx, stopWg)
usedNick.Wait() usedNick.Wait()
server.SetHandler("NICK", nil) server.SetHandler("NICK", nil)
@ -512,6 +528,8 @@ func TestGhostAndIdentify(t *testing.T) {
testStep.Wait() testStep.Wait()
cancel() cancel()
stopWg.Wait()
server.Stop() server.Stop()
expectedCommands := []string{ expectedCommands := []string{
@ -533,7 +551,7 @@ func TestGhostAndIdentify(t *testing.T) {
func TestStopRunningWhenHalfConnected(t *testing.T) { func TestStopRunningWhenHalfConnected(t *testing.T) {
server, port := makeTestServer(t) server, port := makeTestServer(t)
config := makeTestIRCConfig(port) config := makeTestIRCConfig(port)
notifier, _, cancel, stopWg := makeTestNotifier(t, config) notifier, _, ctx, cancel, stopWg := makeTestNotifier(t, config)
var testStep, holdQuitWait sync.WaitGroup var testStep, holdQuitWait sync.WaitGroup
@ -556,12 +574,11 @@ func TestStopRunningWhenHalfConnected(t *testing.T) {
} }
server.SetHandler("QUIT", holdQuit) server.SetHandler("QUIT", holdQuit)
go notifier.Run() go notifier.Run(ctx, stopWg)
testStep.Wait() testStep.Wait()
cancel() cancel()
stopWg.Wait() stopWg.Wait()
holdQuitWait.Wait() holdQuitWait.Wait()

View File

@ -59,12 +59,12 @@ func main() {
alertMsgs := make(chan AlertMsg, config.AlertBufferSize) alertMsgs := make(chan AlertMsg, config.AlertBufferSize)
stopWg.Add(1) stopWg.Add(1)
ircNotifier, err := NewIRCNotifier(ctx, &stopWg, config, alertMsgs, &BackoffMaker{}) ircNotifier, err := NewIRCNotifier(config, alertMsgs, &BackoffMaker{})
if err != nil { if err != nil {
log.Printf("Could not create IRC notifier: %s", err) log.Printf("Could not create IRC notifier: %s", err)
return return
} }
go ircNotifier.Run() go ircNotifier.Run(ctx, &stopWg)
httpServer, err := NewHTTPServer(config, alertMsgs) httpServer, err := NewHTTPServer(config, alertMsgs)
if err != nil { if err != nil {