From 531822f6dcf54f82f1a93156c670ed33f8277b2b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 6 Mar 2026 16:08:15 +0200 Subject: [PATCH] bridgev2/config: add limit for unknown error auto-reconnects --- bridgev2/bridgeconfig/config.go | 47 +++++++++++----------- bridgev2/bridgeconfig/upgrade.go | 1 + bridgev2/bridgestate.go | 10 ++++- bridgev2/matrix/mxmain/example-config.yaml | 3 ++ 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/bridgev2/bridgeconfig/config.go b/bridgev2/bridgeconfig/config.go index 8b9aa019..c301b8d0 100644 --- a/bridgev2/bridgeconfig/config.go +++ b/bridgev2/bridgeconfig/config.go @@ -62,29 +62,30 @@ type CleanupOnLogouts struct { } type BridgeConfig struct { - CommandPrefix string `yaml:"command_prefix"` - PersonalFilteringSpaces bool `yaml:"personal_filtering_spaces"` - PrivateChatPortalMeta bool `yaml:"private_chat_portal_meta"` - AsyncEvents bool `yaml:"async_events"` - SplitPortals bool `yaml:"split_portals"` - ResendBridgeInfo bool `yaml:"resend_bridge_info"` - NoBridgeInfoStateKey bool `yaml:"no_bridge_info_state_key"` - BridgeStatusNotices string `yaml:"bridge_status_notices"` - UnknownErrorAutoReconnect time.Duration `yaml:"unknown_error_auto_reconnect"` - BridgeMatrixLeave bool `yaml:"bridge_matrix_leave"` - BridgeNotices bool `yaml:"bridge_notices"` - TagOnlyOnCreate bool `yaml:"tag_only_on_create"` - OnlyBridgeTags []event.RoomTag `yaml:"only_bridge_tags"` - MuteOnlyOnCreate bool `yaml:"mute_only_on_create"` - DeduplicateMatrixMessages bool `yaml:"deduplicate_matrix_messages"` - CrossRoomReplies bool `yaml:"cross_room_replies"` - OutgoingMessageReID bool `yaml:"outgoing_message_re_id"` - RevertFailedStateChanges bool `yaml:"revert_failed_state_changes"` - KickMatrixUsers bool `yaml:"kick_matrix_users"` - CleanupOnLogout CleanupOnLogouts `yaml:"cleanup_on_logout"` - Relay RelayConfig `yaml:"relay"` - Permissions PermissionConfig `yaml:"permissions"` - Backfill BackfillConfig `yaml:"backfill"` + CommandPrefix string `yaml:"command_prefix"` + PersonalFilteringSpaces bool `yaml:"personal_filtering_spaces"` + PrivateChatPortalMeta bool `yaml:"private_chat_portal_meta"` + AsyncEvents bool `yaml:"async_events"` + SplitPortals bool `yaml:"split_portals"` + ResendBridgeInfo bool `yaml:"resend_bridge_info"` + NoBridgeInfoStateKey bool `yaml:"no_bridge_info_state_key"` + BridgeStatusNotices string `yaml:"bridge_status_notices"` + UnknownErrorAutoReconnect time.Duration `yaml:"unknown_error_auto_reconnect"` + UnknownErrorMaxAutoReconnects int `yaml:"unknown_error_max_auto_reconnects"` + BridgeMatrixLeave bool `yaml:"bridge_matrix_leave"` + BridgeNotices bool `yaml:"bridge_notices"` + TagOnlyOnCreate bool `yaml:"tag_only_on_create"` + OnlyBridgeTags []event.RoomTag `yaml:"only_bridge_tags"` + MuteOnlyOnCreate bool `yaml:"mute_only_on_create"` + DeduplicateMatrixMessages bool `yaml:"deduplicate_matrix_messages"` + CrossRoomReplies bool `yaml:"cross_room_replies"` + OutgoingMessageReID bool `yaml:"outgoing_message_re_id"` + RevertFailedStateChanges bool `yaml:"revert_failed_state_changes"` + KickMatrixUsers bool `yaml:"kick_matrix_users"` + CleanupOnLogout CleanupOnLogouts `yaml:"cleanup_on_logout"` + Relay RelayConfig `yaml:"relay"` + Permissions PermissionConfig `yaml:"permissions"` + Backfill BackfillConfig `yaml:"backfill"` } type MatrixConfig struct { diff --git a/bridgev2/bridgeconfig/upgrade.go b/bridgev2/bridgeconfig/upgrade.go index a0278672..ef51335e 100644 --- a/bridgev2/bridgeconfig/upgrade.go +++ b/bridgev2/bridgeconfig/upgrade.go @@ -33,6 +33,7 @@ func doUpgrade(helper up.Helper) { helper.Copy(up.Bool, "bridge", "no_bridge_info_state_key") helper.Copy(up.Str|up.Null, "bridge", "bridge_status_notices") helper.Copy(up.Str|up.Int|up.Null, "bridge", "unknown_error_auto_reconnect") + helper.Copy(up.Int, "bridge", "unknown_error_max_auto_reconnects") helper.Copy(up.Bool, "bridge", "bridge_matrix_leave") helper.Copy(up.Bool, "bridge", "bridge_notices") helper.Copy(up.Bool, "bridge", "tag_only_on_create") diff --git a/bridgev2/bridgestate.go b/bridgev2/bridgestate.go index babbccab..96d9fd5c 100644 --- a/bridgev2/bridgestate.go +++ b/bridgev2/bridgestate.go @@ -37,6 +37,8 @@ type BridgeStateQueue struct { stopChan chan struct{} stopReconnect atomic.Pointer[context.CancelFunc] + + unknownErrorReconnects int } func (br *Bridge) SendGlobalBridgeState(state status.BridgeState) { @@ -192,8 +194,14 @@ func (bsq *BridgeStateQueue) unknownErrorReconnect(triggeredBy status.BridgeStat } else if prevUnsent.StateEvent != status.StateUnknownError || prev.StateEvent != status.StateUnknownError { log.Debug().Msg("Not reconnecting as the previous state was not an unknown error") return + } else if bsq.unknownErrorReconnects > bsq.bridge.Config.UnknownErrorMaxAutoReconnects { + log.Warn().Msg("Not reconnecting as the maximum number of unknown error reconnects has been reached") + return } - log.Info().Msg("Disconnecting and reconnecting login due to unknown error") + bsq.unknownErrorReconnects++ + log.Info(). + Int("reconnect_num", bsq.unknownErrorReconnects). + Msg("Disconnecting and reconnecting login due to unknown error") bsq.login.Disconnect() log.Debug().Msg("Disconnection finished, recreating client and reconnecting") err := bsq.login.recreateClient(ctx) diff --git a/bridgev2/matrix/mxmain/example-config.yaml b/bridgev2/matrix/mxmain/example-config.yaml index b0e83696..75d0edbf 100644 --- a/bridgev2/matrix/mxmain/example-config.yaml +++ b/bridgev2/matrix/mxmain/example-config.yaml @@ -29,6 +29,9 @@ bridge: # How long after an unknown error should the bridge attempt a full reconnect? # Must be at least 1 minute. The bridge will add an extra ±20% jitter to this value. unknown_error_auto_reconnect: null + # Maximum number of times to do the auto-reconnect above. + # The counter is per login, but is never reset except on logout and restart. + unknown_error_max_auto_reconnects: 10 # Should leaving Matrix rooms be bridged as leaving groups on the remote network? bridge_matrix_leave: false