fix: 修复并发取消逻辑与HTTP请求超时及响应解析
This commit is contained in:
@@ -161,9 +161,8 @@ func BatchModelLambda(ctx context.Context, input any) (any, error) {
|
||||
res := make([][]node.NodeFormField, len(reqMap))
|
||||
var wg sync.WaitGroup
|
||||
|
||||
subCtx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
// 只创建基础上下文,不再主动批量 cancel
|
||||
subCtx := context.WithoutCancel(ctx)
|
||||
// 缓冲1错误通道,仅接收第一个错误
|
||||
errCh := make(chan error, 1)
|
||||
|
||||
@@ -173,7 +172,7 @@ func BatchModelLambda(ctx context.Context, input any) (any, error) {
|
||||
go func(idx int, userItem map[string]any) {
|
||||
defer wg.Done()
|
||||
|
||||
// 上下文已取消则直接退出
|
||||
// 基础上下文仅响应上游原始 ctx 取消,内部任务失败不触发这里
|
||||
select {
|
||||
case <-subCtx.Done():
|
||||
return
|
||||
@@ -181,12 +180,12 @@ func BatchModelLambda(ctx context.Context, input any) (any, error) {
|
||||
}
|
||||
|
||||
singleUserFrom := []map[string]any{userItem}
|
||||
// 下游调用使用 subCtx,不会因为同批次其他任务报错而取消
|
||||
output, err := TextNode(subCtx, nodeInput, skillName, from, singleUserFrom)
|
||||
if err != nil {
|
||||
// 仅第一个错误写入通道
|
||||
// 只往错误通道塞第一个错误,不调用全局 cancel
|
||||
select {
|
||||
case errCh <- err:
|
||||
cancel() // 触发全局取消,其他协程快速退出
|
||||
default:
|
||||
}
|
||||
return
|
||||
@@ -195,26 +194,30 @@ func BatchModelLambda(ctx context.Context, input any) (any, error) {
|
||||
}(idx, item)
|
||||
}
|
||||
|
||||
// 任务全部结束后关闭错误通道
|
||||
// 所有协程跑完再关闭通道
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(errCh)
|
||||
}()
|
||||
|
||||
// ========== 修正后的等待逻辑 ==========
|
||||
// ========== 修复区域 start ==========
|
||||
var execErr error
|
||||
select {
|
||||
// 优先捕获业务错误
|
||||
case execErr = <-errCh:
|
||||
if execErr != nil {
|
||||
// 收到真实业务错误,等待剩余协程收尾后返回
|
||||
wg.Wait()
|
||||
return nil, execErr
|
||||
}
|
||||
// execErr == nil 代表通道关闭、无任何错误,走到下方返回完整结果
|
||||
// 捕获第一个业务错误,等待剩余协程收尾
|
||||
wg.Wait()
|
||||
case <-subCtx.Done():
|
||||
// 上下文被取消,阻塞读完errCh,确认是否存在业务错误
|
||||
// 上游根上下文被终止,读取已存在的错误
|
||||
execErr = <-errCh
|
||||
wg.Wait()
|
||||
if execErr != nil {
|
||||
execErr = fmt.Errorf("global context canceled: %w", execErr)
|
||||
}
|
||||
}
|
||||
|
||||
// 有错误直接返回,不再走结果拼接
|
||||
if execErr != nil {
|
||||
return nil, execErr
|
||||
}
|
||||
|
||||
// 拼接输出结果
|
||||
|
||||
Reference in New Issue
Block a user