win 21325afb33
Some checks failed
CI / test (push) Failing after 10s
CI / frontend (push) Failing after 8s
CI / golangci-lint (push) Failing after 5s
Security Scan / backend-security (push) Failing after 5s
Security Scan / frontend-security (push) Failing after 4s
feat(windsurf): 补全ops日志记录与endpoint派生,对齐其他平台
- windsurf_gateway_service: 添加上游延迟/TTFT/错误上下文记录
- endpoint: DeriveUpstreamEndpoint 添加 PlatformWindsurf 分支
- ops_error_logger: guessPlatformFromPath 添加 /windsurf/ 识别
2026-04-23 20:46:27 +08:00

159 lines
3.5 KiB
Go

package windsurf
import (
"context"
"fmt"
"sync"
)
type LSConnector interface {
Mode() string
Acquire(ctx context.Context, proxyURL string) (*LSLease, error)
Health(ctx context.Context) error
Status() *LSConnectorStatus
}
type LSLease struct {
Mode string
Endpoint string
Client *LocalLSClient
Release func()
}
type LSConnectorStatus struct {
Mode string `json:"mode"`
Healthy bool `json:"healthy"`
Instances int `json:"instances"`
Endpoint string `json:"endpoint,omitempty"`
}
type DockerConnector struct {
host string
port int
csrfToken string
client *LocalLSClient
once sync.Once
}
func NewDockerConnector(host string, port int, csrfToken string) *DockerConnector {
return &DockerConnector{host: host, port: port, csrfToken: csrfToken}
}
func (d *DockerConnector) Mode() string { return "docker" }
func (d *DockerConnector) Acquire(_ context.Context, _ string) (*LSLease, error) {
d.once.Do(func() {
d.client = NewLocalLSClient(d.port, d.csrfToken)
d.client.BaseURL = fmt.Sprintf("http://%s:%d", d.host, d.port)
})
return &LSLease{
Mode: "docker",
Endpoint: fmt.Sprintf("%s:%d", d.host, d.port),
Client: d.client,
Release: func() {},
}, nil
}
func (d *DockerConnector) Health(ctx context.Context) error {
_, err := d.Acquire(ctx, "")
return err
}
func (d *DockerConnector) Status() *LSConnectorStatus {
return &LSConnectorStatus{
Mode: "docker",
Healthy: d.client != nil,
Instances: 1,
Endpoint: fmt.Sprintf("%s:%d", d.host, d.port),
}
}
type EmbeddedConnector struct {
pool *LSPool
}
func NewEmbeddedConnector(pool *LSPool) *EmbeddedConnector {
return &EmbeddedConnector{pool: pool}
}
func (e *EmbeddedConnector) Mode() string { return "embedded" }
func (e *EmbeddedConnector) Acquire(ctx context.Context, proxyURL string) (*LSLease, error) {
entry, err := e.pool.Ensure(ctx, proxyURL)
if err != nil {
return nil, err
}
return &LSLease{
Mode: "embedded",
Endpoint: fmt.Sprintf("localhost:%d", entry.Port),
Client: entry.Client,
Release: func() {},
}, nil
}
func (e *EmbeddedConnector) Health(_ context.Context) error {
status := e.pool.Status()
if !status.Running {
return fmt.Errorf("no LS instances running")
}
return nil
}
func (e *EmbeddedConnector) Status() *LSConnectorStatus {
status := e.pool.Status()
readyCount := 0
for _, inst := range status.Instances {
if inst.Ready {
readyCount++
}
}
return &LSConnectorStatus{
Mode: "embedded",
Healthy: readyCount > 0,
Instances: len(status.Instances),
}
}
type ExternalConnector struct {
baseURL string
port int
csrfToken string
client *LocalLSClient
once sync.Once
}
func NewExternalConnector(baseURL string, port int, csrfToken string) *ExternalConnector {
return &ExternalConnector{baseURL: baseURL, port: port, csrfToken: csrfToken}
}
func (x *ExternalConnector) Mode() string { return "external" }
func (x *ExternalConnector) Acquire(_ context.Context, _ string) (*LSLease, error) {
x.once.Do(func() {
x.client = NewLocalLSClient(x.port, x.csrfToken)
if x.baseURL != "" {
x.client.BaseURL = x.baseURL
}
})
return &LSLease{
Mode: "external",
Endpoint: x.baseURL,
Client: x.client,
Release: func() {},
}, nil
}
func (x *ExternalConnector) Health(ctx context.Context) error {
_, err := x.Acquire(ctx, "")
return err
}
func (x *ExternalConnector) Status() *LSConnectorStatus {
return &LSConnectorStatus{
Mode: "external",
Healthy: x.client != nil,
Instances: 1,
Endpoint: x.baseURL,
}
}