将 Worker 发现、路由画像、容量与执行传输抽象为平台无关接口,新增 Kubernetes 和静态容量适配器,并以 shadow 模式接入生产配置。 实现网络与容量评分、路由防抖、池队列、同步 Worker 租约、一次性执行令牌,以及提交状态不明时禁止重复分配的安全语义。 新增 0105 兼容迁移、管理接口、指标、OpenAPI 和回归测试。已执行全量 Go 测试、go vet、OpenAPI、迁移安全、Compose 与 Kustomize 验证。
51 lines
1.6 KiB
Go
51 lines
1.6 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/easyai/easyai-ai-gateway/apps/api/internal/clients"
|
|
"github.com/easyai/easyai-ai-gateway/apps/api/internal/runner"
|
|
)
|
|
|
|
const maxInternalExecutionRequestBytes = 64 * 1024
|
|
|
|
func (s *Server) internalExecution(w http.ResponseWriter, r *http.Request) {
|
|
body := http.MaxBytesReader(w, r.Body, maxInternalExecutionRequestBytes)
|
|
defer body.Close()
|
|
var input runner.InternalExecutionRequest
|
|
decoder := json.NewDecoder(body)
|
|
decoder.DisallowUnknownFields()
|
|
if err := decoder.Decode(&input); err != nil {
|
|
http.Error(w, "invalid internal execution request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
var trailing any
|
|
if err := decoder.Decode(&trailing); err != io.EOF {
|
|
http.Error(w, "invalid internal execution request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/x-ndjson")
|
|
w.Header().Set("Cache-Control", "no-store")
|
|
encoder := json.NewEncoder(w)
|
|
flusher, _ := w.(http.Flusher)
|
|
writeFrame := func(frame runner.InternalExecutionFrame) error {
|
|
if err := encoder.Encode(frame); err != nil {
|
|
return err
|
|
}
|
|
if flusher != nil {
|
|
flusher.Flush()
|
|
}
|
|
return nil
|
|
}
|
|
result, err := s.runner.ExecuteInternal(r.Context(), r.Header.Get("Authorization"), input, func(delta clients.StreamDeltaEvent) error {
|
|
return writeFrame(runner.InternalExecutionFrame{Type: "delta", Delta: &delta})
|
|
})
|
|
if err != nil {
|
|
_ = writeFrame(runner.InternalExecutionFrameForError(err))
|
|
return
|
|
}
|
|
_ = writeFrame(runner.InternalExecutionFrame{Type: "result", Output: result.Output, Wire: result.Wire})
|
|
}
|