Skip to content

Commit c79c528

Browse files
DouDOU-startclaude
andcommitted
fix(plugin): extend image host forward timeout
Allow image generation requests to use the five-minute host forward window while keeping regular requests on the existing timeout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4e354a0 commit c79c528

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

backend/internal/plugin/host_service.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ func (h *HostService) forward(ctx context.Context, req *pb.HostForwardRequest) (
459459
if err != nil {
460460
return nil, err
461461
}
462-
fwdCtx, cancel := context.WithTimeout(ctx, 120*time.Second)
462+
fwdCtx, cancel := context.WithTimeout(ctx, hostForwardTimeout(req))
463463
defer cancel()
464464

465465
var hardExclude []int
@@ -706,7 +706,18 @@ func (h *HostService) forwardStream(ctx context.Context, req *pb.HostForwardRequ
706706
}
707707

708708
// maxHostForwardAttempts 最大 failover 次数,与 Forwarder 保持一致。
709-
const maxHostForwardAttempts = 3
709+
const (
710+
maxHostForwardAttempts = 3
711+
defaultHostForwardTimeout = 120 * time.Second
712+
imageHostForwardTimeout = 300 * time.Second
713+
)
714+
715+
func hostForwardTimeout(req *pb.HostForwardRequest) time.Duration {
716+
if req != nil && requestNeedsImage(req.Path, req.Model) {
717+
return imageHostForwardTimeout
718+
}
719+
return defaultHostForwardTimeout
720+
}
710721

711722
// failoverStreamWriter 包装 hostStreamWriter,支持 failover 重试。
712723
// 成功响应(StatusCode < 400)立即提交到真正的 gRPC stream,实现真流式;

backend/internal/plugin/host_service_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,38 @@ package plugin
33
import (
44
"context"
55
"testing"
6+
"time"
67

78
"entgo.io/ent/dialect/sql/schema"
89
_ "github.com/mattn/go-sqlite3"
910
"google.golang.org/grpc/codes"
1011
"google.golang.org/grpc/status"
1112

1213
"github.com/DouDOU-start/airgate-core/ent/enttest"
14+
pb "github.com/DouDOU-start/airgate-sdk/proto"
1315
)
1416

17+
func TestHostForwardTimeout(t *testing.T) {
18+
cases := []struct {
19+
name string
20+
req *pb.HostForwardRequest
21+
want time.Duration
22+
}{
23+
{name: "nil request", req: nil, want: defaultHostForwardTimeout},
24+
{name: "chat request", req: &pb.HostForwardRequest{Path: "/v1/chat/completions", Model: "gpt-4o"}, want: defaultHostForwardTimeout},
25+
{name: "images API request", req: &pb.HostForwardRequest{Path: "/v1/images/generations", Model: "gpt-4o"}, want: imageHostForwardTimeout},
26+
{name: "image model request", req: &pb.HostForwardRequest{Path: "/v1/responses", Model: "gpt-image-2"}, want: imageHostForwardTimeout},
27+
}
28+
29+
for _, tc := range cases {
30+
t.Run(tc.name, func(t *testing.T) {
31+
if got := hostForwardTimeout(tc.req); got != tc.want {
32+
t.Fatalf("hostForwardTimeout() = %s, want %s", got, tc.want)
33+
}
34+
})
35+
}
36+
}
37+
1538
func TestCheckHostForwardBalance(t *testing.T) {
1639
ctx := context.Background()
1740
db := enttest.Open(t, "sqlite3", "file:host_forward_balance?mode=memory&cache=shared&_fk=1", enttest.WithMigrateOptions(schema.WithGlobalUniqueID(false)))

0 commit comments

Comments
 (0)