performChannelTests runs the channel test loop synchronously, honoring ctx cancellation so a system-task runner that loses its lease stops promptly. When report is non-nil it is called after each channel with (processed, total) so the system task can surface progress.
(ctx context.Context, channels []*model.Channel, testUserID int, allowDisable bool, report func(processed, total int))
| 905 | // report is non-nil it is called after each channel with (processed, total) so |
| 906 | // the system task can surface progress. |
| 907 | func performChannelTests(ctx context.Context, channels []*model.Channel, testUserID int, allowDisable bool, report func(processed, total int)) channelTestSummary { |
| 908 | summary := channelTestSummary{} |
| 909 | var disableThreshold = int64(common.ChannelDisableThreshold * 1000) |
| 910 | if disableThreshold == 0 { |
| 911 | disableThreshold = 10000000 // a impossible value |
| 912 | } |
| 913 | |
| 914 | total := len(channels) |
| 915 | for index, channel := range channels { |
| 916 | if ctx != nil && ctx.Err() != nil { |
| 917 | break |
| 918 | } |
| 919 | if report != nil { |
| 920 | report(index, total) // channels completed before this one |
| 921 | } |
| 922 | if channel.Status == common.ChannelStatusManuallyDisabled { |
| 923 | continue |
| 924 | } |
| 925 | isChannelEnabled := channel.Status == common.ChannelStatusEnabled |
| 926 | tik := time.Now() |
| 927 | result := testChannel(ctx, channel, testUserID, "", "", shouldUseStreamForAutomaticChannelTest(channel)) |
| 928 | tok := time.Now() |
| 929 | milliseconds := tok.Sub(tik).Milliseconds() |
| 930 | if ctx != nil && ctx.Err() != nil { |
| 931 | break |
| 932 | } |
| 933 | |
| 934 | summary.Tested++ |
| 935 | |
| 936 | shouldBanChannel := false |
| 937 | newAPIError := result.newAPIError |
| 938 | // request error disables the channel |
| 939 | if newAPIError != nil { |
| 940 | shouldBanChannel = service.ShouldDisableChannel(result.newAPIError) |
| 941 | } |
| 942 | |
| 943 | // 当错误检查通过,才检查响应时间 |
| 944 | if common.AutomaticDisableChannelEnabled && !shouldBanChannel { |
| 945 | if milliseconds > disableThreshold { |
| 946 | err := fmt.Errorf("响应时间 %.2fs 超过阈值 %.2fs", float64(milliseconds)/1000.0, float64(disableThreshold)/1000.0) |
| 947 | newAPIError = types.NewOpenAIError(err, types.ErrorCodeChannelResponseTimeExceeded, http.StatusRequestTimeout) |
| 948 | shouldBanChannel = true |
| 949 | } |
| 950 | } |
| 951 | |
| 952 | if newAPIError == nil { |
| 953 | summary.Succeeded++ |
| 954 | } else { |
| 955 | summary.Failed++ |
| 956 | } |
| 957 | |
| 958 | // disable channel |
| 959 | if allowDisable && isChannelEnabled && shouldBanChannel && channel.GetAutoBan() { |
| 960 | processChannelError(result.context, *types.NewChannelError(channel.Id, channel.Type, channel.Name, channel.ChannelInfo.IsMultiKey, common.GetContextKeyString(result.context, constant.ContextKeyChannelKey), channel.GetAutoBan()), newAPIError) |
| 961 | summary.Disabled++ |
| 962 | } |
| 963 | |
| 964 | // enable channel |
no test coverage detected