fix(irc): improve IRC handler management (#1269)

* fix some races in IRC handler management

* remove go 1.21 and slices package

* chore: update deps

* fix: use exp/slices pkg and client callbacks

* fix(irc): remove deadlock mutex from authenticate

* restore locking in authenticate()

* fix(irc): data races

* fix(irc): do not allow restart of disabled network

* fix(irc): disable restart btn if net disabled

---------

Co-authored-by: ze0s <43699394+zze0s@users.noreply.github.com>
This commit is contained in:
Shivaram Lingamneni 2023-12-12 11:29:43 -08:00 committed by GitHub
parent 17e97201fd
commit b2c32a421e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 230 additions and 194 deletions

View file

@ -9,7 +9,6 @@ import (
"fmt"
"strings"
"sync"
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/indexer"
@ -127,7 +126,7 @@ func (s *service) startNetwork(network domain.IrcNetwork) error {
if existingHandler, found := s.handlers[network.ID]; found {
s.log.Debug().Msgf("starting network: %s", network.Name)
if !existingHandler.client.Connected() {
if existingHandler.Stopped() {
go func(handler *Handler) {
if err := handler.Run(); err != nil {
s.log.Error().Err(err).Msgf("failed to start existing handler for network: %s", handler.network.Name)
@ -178,7 +177,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
// if server, tls, invite command, port : changed - restart
// if nickserv account, nickserv password : changed - stay connected, and change those
// if channels len : changes - join or leave
if existingHandler.client.Connected() {
if !existingHandler.Stopped() {
handler := existingHandler.GetNetwork()
restartNeeded := false
var fieldsChanged []string
@ -341,6 +340,10 @@ func (s *service) RestartNetwork(ctx context.Context, id int64) error {
return err
}
if !network.Enabled {
return errors.New("network disabled, could not restart")
}
return s.restartNetwork(*network)
}
@ -459,26 +462,7 @@ func (s *service) GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetwor
handler, ok := s.handlers[n.ID]
if ok {
handler.m.RLock()
// only set connected and connected since if we have an active handler and connection
if handler.client.Connected() {
netw.Connected = handler.connectedSince != time.Time{}
netw.ConnectedSince = handler.connectedSince
// current and preferred nick is only available if the network is connected
netw.CurrentNick = handler.CurrentNick()
netw.PreferredNick = handler.PreferredNick()
}
netw.Healthy = handler.Healthy()
// if we have any connection errors like bad nickserv auth add them here
if len(handler.connectionErrors) > 0 {
netw.ConnectionErrors = handler.connectionErrors
}
handler.m.RUnlock()
handler.ReportStatus(&netw)
}
channels, err := s.repo.ListChannels(n.ID)