فهرست منبع

Retry connecting a few times if connection fails on startup

Tulir Asokan 2 سال پیش
والد
کامیت
587cf8a17e
1فایلهای تغییر یافته به همراه21 افزوده شده و 12 حذف شده
  1. 21 12
      user.go

+ 21 - 12
user.go

@@ -219,18 +219,7 @@ func (br *DiscordBridge) startUsers() {
 
 	usersWithToken := br.getAllUsersWithToken()
 	for _, u := range usersWithToken {
-		go func(user *User) {
-			user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnecting})
-			err := user.Connect()
-			if err != nil {
-				user.log.Errorfln("Error connecting: %v", err)
-				if closeErr := (&websocket.CloseError{}); errors.As(err, &closeErr) && closeErr.Code == 4004 {
-					user.invalidAuthHandler(nil, nil)
-				} else {
-					user.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "dc-unknown-websocket-error", Message: err.Error()})
-				}
-			}
-		}(u)
+		go u.startupTryConnect(0)
 	}
 	if len(usersWithToken) == 0 {
 		br.SendGlobalBridgeState(status.BridgeState{StateEvent: status.StateUnconfigured}.Fill(nil))
@@ -248,6 +237,26 @@ func (br *DiscordBridge) startUsers() {
 	}
 }
 
+func (user *User) startupTryConnect(retryCount int) {
+	user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnecting})
+	err := user.Connect()
+	if err != nil {
+		user.log.Errorfln("Error connecting: %v", err)
+		closeErr := &websocket.CloseError{}
+		if errors.As(err, &closeErr) && closeErr.Code == 4004 {
+			user.invalidAuthHandler(nil, nil)
+		} else if retryCount < 6 {
+			user.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "dc-unknown-websocket-error", Message: err.Error()})
+			retryInSeconds := 2 << retryCount
+			user.log.Debugfln("Retrying connection in %d seconds", retryInSeconds)
+			time.Sleep(time.Duration(retryInSeconds) * time.Second)
+			user.startupTryConnect(retryCount + 1)
+		} else {
+			user.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "dc-unknown-websocket-error", Message: err.Error()})
+		}
+	}
+}
+
 func (user *User) SetManagementRoom(roomID id.RoomID) {
 	user.bridge.managementRoomsLock.Lock()
 	defer user.bridge.managementRoomsLock.Unlock()