Cancel reconnect retries during shutdown

This commit is contained in:
Brandon McGinty (chatgpt)
2026-08-10 10:24:38 -04:00
committed by Brandon McGinty
parent e68546eec5
commit 1d6ab79ed0
4 changed files with 51 additions and 5 deletions
+23
View File
@@ -83,6 +83,9 @@ type Barnard struct {
adminBanList gumble.BanList
adminUserList gumble.RegisteredUsers
adminACL *gumble.ACL
reconnectStop chan struct{}
reconnectStopOnce sync.Once
}
// cleanupConnectionAudio releases connection-owned audio resources before a
@@ -174,6 +177,26 @@ func (b *Barnard) setConnected(connected bool) {
b.stateMutex.Unlock()
}
func (b *Barnard) stopReconnects() {
b.reconnectStopOnce.Do(func() {
if b.reconnectStop != nil {
close(b.reconnectStop)
}
})
}
func (b *Barnard) reconnectCanceled() bool {
if b.reconnectStop == nil {
return false
}
select {
case <-b.reconnectStop:
return true
default:
return false
}
}
func (b *Barnard) StopTransmission() {
if b.isTransmitting() {
b.Notify("micdown", "me", "")
+9 -5
View File
@@ -14,6 +14,7 @@ import (
)
func (b *Barnard) start() {
b.reconnectStop = make(chan struct{})
b.Config.Attach(gumbleutil.AutoBitrate)
b.Config.Attach(b)
b.Config.Address = b.Address
@@ -218,12 +219,15 @@ func (b *Barnard) OnDisconnect(e *gumble.DisconnectEvent) {
}
func (b *Barnard) reconnectGoroutine() {
for {
res := b.connect(true)
if res == true {
break
for !b.reconnectCanceled() {
if b.connect(true) {
return
}
select {
case <-b.reconnectStop:
return
case <-time.After(15 * time.Second):
}
time.Sleep(15 * time.Second)
}
}
+17
View File
@@ -193,6 +193,23 @@ func TestCleanupConnectionAudioIsIdempotent(t *testing.T) {
// Tone test mode intentionally does not create an OpenAL stream. Tree
// controls must therefore keep local mute state without trying to update one.
func TestReconnectCancellationIsSafeBeforeStartup(t *testing.T) {
b := &Barnard{}
b.stopReconnects()
if b.reconnectCanceled() {
t.Fatal("nil reconnect channel should not report cancellation")
}
}
func TestReconnectCancellationStopsWaiters(t *testing.T) {
b := &Barnard{reconnectStop: make(chan struct{})}
b.stopReconnects()
if !b.reconnectCanceled() {
t.Fatal("expected reconnect cancellation")
}
b.stopReconnects() // repeated shutdown must not panic
}
func TestUpdateUserGainAllowsToneTestWithoutStream(t *testing.T) {
(&Barnard{ToneTest: true}).updateUserGain(&gumble.User{})
}
+2
View File
@@ -393,12 +393,14 @@ func (b *Barnard) OnMicVolumeUp(ui *uiterm.Ui, key uiterm.Key) {
}
func (b *Barnard) OnQuitPress(ui *uiterm.Ui, key uiterm.Key) {
b.stopReconnects()
b.StopRecordingIfActive(true)
b.Client.Disconnect()
b.Ui.Close()
}
func (b *Barnard) CommandExit(ui *uiterm.Ui, cmd string) {
b.stopReconnects()
b.StopRecordingIfActive(true)
b.Client.Disconnect()
b.Ui.Close()