补齐 Grok Realtime 握手失败账号冷却
This commit is contained in:
@@ -98,6 +98,12 @@ func (h *OpenAIGatewayHandler) GrokRealtime(c *gin.Context) {
|
||||
cancelProbe()
|
||||
if openErr != nil {
|
||||
reqLog.Warn("grok_realtime.pre_accept_failed", zap.Int64("account_id", account.ID), zap.Error(openErr))
|
||||
statusCode := http.StatusBadGateway
|
||||
var dialErr *service.GrokRealtimeDialError
|
||||
if errors.As(openErr, &dialErr) && dialErr.StatusCode > 0 {
|
||||
statusCode = dialErr.StatusCode
|
||||
}
|
||||
h.gatewayService.HandleGrokRealtimeUpstreamError(c.Request.Context(), account, statusCode, []byte(openErr.Error()))
|
||||
release()
|
||||
release = nil
|
||||
failed[account.ID] = struct{}{}
|
||||
|
||||
@@ -139,6 +139,16 @@ func (s *OpenAIGatewayService) ProxyGrokRealtime(ctx context.Context, c *gin.Con
|
||||
|
||||
type GrokRealtimeUpstream struct{ conn openAIWSClientConn }
|
||||
|
||||
// GrokRealtimeDialError preserves an HTTP status returned before WebSocket
|
||||
// upgrade so handlers can apply the normal Grok account policy.
|
||||
type GrokRealtimeDialError struct {
|
||||
StatusCode int
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *GrokRealtimeDialError) Error() string { return e.Err.Error() }
|
||||
func (e *GrokRealtimeDialError) Unwrap() error { return e.Err }
|
||||
|
||||
func (u *GrokRealtimeUpstream) Close() error {
|
||||
if u == nil || u.conn == nil {
|
||||
return nil
|
||||
@@ -171,13 +181,22 @@ func (s *OpenAIGatewayService) OpenGrokRealtime(ctx context.Context, account *Ac
|
||||
if account.ProxyID != nil && account.Proxy != nil {
|
||||
proxyURL = account.Proxy.URL()
|
||||
}
|
||||
conn, _, _, err := s.getOpenAIWSPassthroughDialer().Dial(ctx, u.String(), headers, proxyURL)
|
||||
conn, status, _, err := s.getOpenAIWSPassthroughDialer().Dial(ctx, u.String(), headers, proxyURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, &GrokRealtimeDialError{StatusCode: status, Err: err}
|
||||
}
|
||||
return &GrokRealtimeUpstream{conn: conn}, nil
|
||||
}
|
||||
|
||||
// HandleGrokRealtimeUpstreamError applies the shared Grok account policy to a
|
||||
// failed pre-accept WebSocket handshake.
|
||||
func (s *OpenAIGatewayService) HandleGrokRealtimeUpstreamError(ctx context.Context, account *Account, statusCode int, body []byte) {
|
||||
if statusCode <= 0 {
|
||||
statusCode = http.StatusBadGateway
|
||||
}
|
||||
s.handleGrokAccountUpstreamError(ctx, account, statusCode, nil, body)
|
||||
}
|
||||
|
||||
func (s *OpenAIGatewayService) ProxyGrokRealtimeConn(ctx context.Context, c *gin.Context, client *coderws.Conn, upstream *GrokRealtimeUpstream) (bool, error) {
|
||||
if s == nil || client == nil || upstream == nil || upstream.conn == nil {
|
||||
return false, fmt.Errorf("realtime connection is required")
|
||||
|
||||
Reference in New Issue
Block a user