дȫÏîĿÉó²éÎÊÌⲢ·¢²¼ v1.1.9
¸ÄÓñ¾»ú¶ÀÁ¢ CA£¬»ָ´ CLI TLS УÑ飬±£»¤ƾ¾ÝÓëÅäÖò¢·¢±£´档 д Cursor Êý¾ݡ¢»Ự·¾¶¡¢´úÀíÉúÃüÖÜÆڡ¢ģÐÍÇëÇóÓë Skills Îļþ²Ù×÷¡£ Ϊ¶ÀÁ¢ Tab ·þÎñÔö¼ӿͻ§¶˼øȨ£¬Éý¼¶ÒÀÀµÓ빤¾ßÁ´£¬ÍêÉƷ¢²¼ԪÐÅϢͬ²½¡£ Ñé֤£ºÁ½¸ö Go ģ¿éµIJâÊÔ/vet¡¢¹ؼüģ¿é race¡¢ǰ¶˲âÊÔ/Éú²ú¹¹½¨/Éó¼ơ¢ Go ¿ɴï©¶´ɨÃèÓë macOS/Linux ¿ÉÐÐģ¿齻²æ±àÒë¾ùͨ¹ý¡£ Windows ¸ôÀëÆô¶¯ͨ¹ý£»δÍê³ɵĵã»÷ðÑ̺ÍԭÉúƽ̨Ñé֤¼ûÉó²鱨¸档
This commit is contained in:
@@ -2,6 +2,7 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"cursor/internal/appdata"
|
||||
serverconfig "cursor/internal/backend/server/config"
|
||||
@@ -22,8 +23,8 @@ func (s *ProxyService) LoadUserConfig() (UserConfig, error) {
|
||||
if app != nil {
|
||||
ctx = app.Context()
|
||||
}
|
||||
if s.backendHost != nil {
|
||||
return s.backendHost.LoadConfig(ctx)
|
||||
if s.backend() != nil {
|
||||
return s.backend().LoadConfig(ctx)
|
||||
}
|
||||
if s.store == nil {
|
||||
return serverconfig.DefaultConfig(), nil
|
||||
@@ -36,6 +37,9 @@ func (s *ProxyService) SaveUserConfig(cfg UserConfig) error {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
if cfg.Revision == "" {
|
||||
return fmt.Errorf("配置缺少 revision,请重新加载后保存")
|
||||
}
|
||||
app := application.Get()
|
||||
ctx := context.Background()
|
||||
if app != nil {
|
||||
@@ -45,8 +49,8 @@ func (s *ProxyService) SaveUserConfig(cfg UserConfig) error {
|
||||
normalized UserConfig
|
||||
err error
|
||||
)
|
||||
if s.backendHost != nil {
|
||||
normalized, err = s.backendHost.SaveConfig(ctx, cfg)
|
||||
if s.backend() != nil {
|
||||
normalized, err = s.backend().SaveConfig(ctx, cfg)
|
||||
} else if s.store != nil {
|
||||
normalized, err = s.store.Save(ctx, cfg)
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
goruntime "runtime"
|
||||
|
||||
@@ -10,7 +11,7 @@ import (
|
||||
|
||||
// ApplyCursorSettings 用于处理与 ApplyCursorSettings 相关的逻辑。
|
||||
func (s *ProxyService) ApplyCursorSettings() error {
|
||||
if s == nil || s.proxy == nil {
|
||||
if s == nil || s.proxyServer() == nil {
|
||||
return fmt.Errorf("proxy is not initialized")
|
||||
}
|
||||
s.caFileMu.Lock()
|
||||
@@ -37,7 +38,7 @@ func (s *ProxyService) ApplyCursorSettings() error {
|
||||
}
|
||||
}
|
||||
|
||||
proxyURL := cursor.ProxyURLFromListenAddr(s.proxy.Snapshot().ListenAddr)
|
||||
proxyURL := cursor.ProxyURLFromListenAddr(s.proxyServer().Snapshot().ListenAddr)
|
||||
|
||||
if err := cursor.WriteUserProxySettings(proxyURL); err != nil {
|
||||
return err
|
||||
@@ -48,8 +49,8 @@ func (s *ProxyService) ApplyCursorSettings() error {
|
||||
// 如果未检测到 CLI 安装,跳过但不报错
|
||||
if cliPath := cursor.DetectCLIInstallPath(); cliPath != "" {
|
||||
cliHTTPSAddr := ""
|
||||
if s.backendHost != nil {
|
||||
cliHTTPSAddr = s.backendHost.CLIHTTPSListenAddr()
|
||||
if s.backend() != nil {
|
||||
cliHTTPSAddr = s.backend().CLIHTTPSListenAddr()
|
||||
}
|
||||
if err := cursor.WriteCLIProxyWrapper(cliHTTPSAddr, caCertPath); err != nil {
|
||||
logger.Errorf("write cli proxy wrapper failed: %v", err)
|
||||
@@ -68,22 +69,21 @@ func (s *ProxyService) ApplyCursorSettings() error {
|
||||
|
||||
// ClearCursorSettings 用于处理与 ClearCursorSettings 相关的逻辑。
|
||||
func (s *ProxyService) ClearCursorSettings() error {
|
||||
var errs []error
|
||||
if goruntime.GOOS == "darwin" {
|
||||
if err := cursor.ClearSystemNodeExtraCACerts(); err != nil {
|
||||
return err
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if err := cursor.ClearUserProxySettings(); err != nil {
|
||||
return err
|
||||
for _, clear := range []func() error{cursor.ClearUserProxySettings, cursor.ClearCLIProxyWrapper, cursor.ClearCLIAuthFile} {
|
||||
if err := clear(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if err := cursor.ClearCLIProxyWrapper(); err != nil {
|
||||
logger.Errorf("clear cli proxy wrapper failed: %v", err)
|
||||
if len(errs) == 0 {
|
||||
s.setCursorSettingsApplied(false)
|
||||
}
|
||||
if err := cursor.ClearCLIAuthFile(); err != nil {
|
||||
logger.Errorf("clear cli auth.json failed: %v", err)
|
||||
}
|
||||
s.setCursorSettingsApplied(false)
|
||||
return nil
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// GetDeviceID 用于处理与 GetDeviceID 相关的逻辑。
|
||||
|
||||
@@ -58,8 +58,34 @@ type ProxyState struct {
|
||||
|
||||
// StartProxy 用于处理与 StartProxy 相关的逻辑。
|
||||
func (s *ProxyService) StartProxy() (ProxyState, error) {
|
||||
if s == nil {
|
||||
return ProxyState{}, fmt.Errorf("服务未初始化")
|
||||
}
|
||||
s.lifecycleMu.Lock()
|
||||
defer s.lifecycleMu.Unlock()
|
||||
if s.backend() != nil && s.backend().IsRunning() && s.proxyServer() != nil && s.proxyServer().IsRunning() {
|
||||
return s.GetState(), nil
|
||||
}
|
||||
startedBackend, startedProxy, settingsAttempted := false, false, false
|
||||
rollback := func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
if startedProxy && s.proxyServer() != nil {
|
||||
_ = s.proxyServer().Stop(ctx)
|
||||
}
|
||||
if settingsAttempted {
|
||||
if err := s.ClearCursorSettings(); err != nil {
|
||||
logger.Error("startup rollback failed", "error", err)
|
||||
}
|
||||
}
|
||||
if startedBackend && s.backend() != nil {
|
||||
_ = s.backend().Stop(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
logger.Infof("start service requested config_path=%s logs_root=%s", s.configPath, s.logsRoot)
|
||||
fail := func(step string, err error) (ProxyState, error) {
|
||||
rollback()
|
||||
logger.Errorf("start service failed step=%s err=%v", step, err)
|
||||
s.setLastError(err)
|
||||
s.emitState()
|
||||
@@ -72,51 +98,43 @@ func (s *ProxyService) StartProxy() (ProxyState, error) {
|
||||
if err := s.ensureBackendHost(); err != nil {
|
||||
return fail("ensure_backend_host", err)
|
||||
}
|
||||
if !s.backendHost.IsRunning() {
|
||||
logger.Infof("starting embedded backend listen_addr=%s", s.backendHost.ListenAddr())
|
||||
if err := s.backendHost.Start(); err != nil {
|
||||
if !s.backend().IsRunning() {
|
||||
logger.Infof("starting embedded backend listen_addr=%s", s.backend().ListenAddr())
|
||||
if err := s.backend().Start(); err != nil {
|
||||
return fail("start_backend", err)
|
||||
}
|
||||
startedBackend = true
|
||||
} else {
|
||||
logger.Infof("embedded backend already running listen_addr=%s", s.backendHost.ListenAddr())
|
||||
logger.Infof("embedded backend already running listen_addr=%s", s.backend().ListenAddr())
|
||||
}
|
||||
healthCtx, healthCancel := context.WithTimeout(context.Background(), backendReadyTimeout)
|
||||
defer healthCancel()
|
||||
if err := s.waitForBackend(healthCtx); err != nil {
|
||||
return fail("wait_backend_ready", err)
|
||||
}
|
||||
logger.Infof("embedded backend ready listen_addr=%s", s.backendHost.ListenAddr())
|
||||
logger.Infof("embedded backend ready listen_addr=%s", s.backend().ListenAddr())
|
||||
if err := s.ensureProxy(cfg); err != nil {
|
||||
return fail("ensure_proxy", err)
|
||||
}
|
||||
|
||||
if s.proxyServer() != nil && !s.proxyServer().IsRunning() {
|
||||
logger.Infof("starting mitm proxy listen_addr=%s", s.proxyServer().Snapshot().ListenAddr)
|
||||
if err := s.proxyServer().Start(); err != nil {
|
||||
return fail("start_mitm_proxy", err)
|
||||
}
|
||||
startedProxy = true
|
||||
}
|
||||
|
||||
settingsAttempted = true
|
||||
if err := s.ApplyCursorSettings(); err != nil {
|
||||
return fail("apply_cursor_settings", err)
|
||||
}
|
||||
// 启动时注入账号信息
|
||||
if err := cursor.InjectCursorUserInfo(localruntime.InjectAccountEmail, localruntime.InjectAuthToken); err != nil {
|
||||
logger.Errorf("injectCursorUserInfo failed: %v", err)
|
||||
// 不阻断启动,仅记录日志
|
||||
}
|
||||
|
||||
if s.proxy != nil && !s.proxy.IsRunning() {
|
||||
logger.Infof("starting mitm proxy listen_addr=%s", s.proxy.Snapshot().ListenAddr)
|
||||
if err := s.proxy.Start(); err != nil {
|
||||
return fail("start_mitm_proxy", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.ApplyCursorSettings(); err != nil {
|
||||
stopCtx, stopCancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer stopCancel()
|
||||
if s.proxy != nil {
|
||||
_ = s.proxy.Stop(stopCtx)
|
||||
}
|
||||
_ = s.backendHost.Stop(stopCtx)
|
||||
startErr := fmt.Errorf("服务已启动,但注入 Cursor 配置失败: %w", err)
|
||||
logger.Errorf("start service failed step=apply_cursor_settings err=%v", startErr)
|
||||
s.setLastError(startErr)
|
||||
s.emitState()
|
||||
return s.GetState(), startErr
|
||||
}
|
||||
|
||||
s.setLastError(nil)
|
||||
s.emitState()
|
||||
state := s.GetState()
|
||||
@@ -133,6 +151,11 @@ func (s *ProxyService) StartProxy() (ProxyState, error) {
|
||||
// 各清理步骤失败时记录错误但继续执行后续步骤,保证 backend 最终被停止,
|
||||
// 避免"Cursor 配置已清理但 backend 仍在运行"的不一致状态。
|
||||
func (s *ProxyService) StopProxy() (ProxyState, error) {
|
||||
if s == nil {
|
||||
return ProxyState{}, nil
|
||||
}
|
||||
s.lifecycleMu.Lock()
|
||||
defer s.lifecycleMu.Unlock()
|
||||
logger.Infof("stop service requested")
|
||||
var stopErrors []error
|
||||
fail := func(step string, err error) {
|
||||
@@ -144,15 +167,15 @@ func (s *ProxyService) StopProxy() (ProxyState, error) {
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
if s.proxy != nil && s.proxy.IsRunning() {
|
||||
logger.Infof("stopping mitm proxy listen_addr=%s", s.proxy.Snapshot().ListenAddr)
|
||||
fail("stop_mitm_proxy", s.proxy.Stop(ctx))
|
||||
if s.proxyServer() != nil && s.proxyServer().IsRunning() {
|
||||
logger.Infof("stopping mitm proxy listen_addr=%s", s.proxyServer().Snapshot().ListenAddr)
|
||||
fail("stop_mitm_proxy", s.proxyServer().Stop(ctx))
|
||||
}
|
||||
|
||||
fail("clear_cursor_settings", s.ClearCursorSettings())
|
||||
if s.backendHost != nil {
|
||||
logger.Infof("stopping embedded backend listen_addr=%s", s.backendHost.ListenAddr())
|
||||
fail("stop_backend", s.backendHost.Stop(ctx))
|
||||
if s.backend() != nil {
|
||||
logger.Infof("stopping embedded backend listen_addr=%s", s.backend().ListenAddr())
|
||||
fail("stop_backend", s.backend().Stop(ctx))
|
||||
}
|
||||
|
||||
if len(stopErrors) > 0 {
|
||||
@@ -177,8 +200,8 @@ func (s *ProxyService) StopProxy() (ProxyState, error) {
|
||||
// GetState 用于处理与 GetState 相关的逻辑。
|
||||
func (s *ProxyService) GetState() ProxyState {
|
||||
var proxySnap mitm.Snapshot
|
||||
if s.proxy != nil {
|
||||
proxySnap = s.proxy.Snapshot()
|
||||
if s.proxyServer() != nil {
|
||||
proxySnap = s.proxyServer().Snapshot()
|
||||
}
|
||||
s.mu.RLock()
|
||||
lastError := s.lastError
|
||||
@@ -188,11 +211,11 @@ func (s *ProxyService) GetState() ProxyState {
|
||||
backendRunning := false
|
||||
cliHTTPSListenAddr := ""
|
||||
cliHTTPSRunning := false
|
||||
if s.backendHost != nil {
|
||||
backendListenAddr = s.backendHost.ListenAddr()
|
||||
backendRunning = s.backendHost.IsRunning()
|
||||
cliHTTPSListenAddr = s.backendHost.CLIHTTPSListenAddr()
|
||||
cliHTTPSRunning = s.backendHost.CLIHTTPSRunning()
|
||||
if s.backend() != nil {
|
||||
backendListenAddr = s.backend().ListenAddr()
|
||||
backendRunning = s.backend().IsRunning()
|
||||
cliHTTPSListenAddr = s.backend().CLIHTTPSListenAddr()
|
||||
cliHTTPSRunning = s.backend().CLIHTTPSRunning()
|
||||
}
|
||||
netProxy := netproxy.CurrentStatus()
|
||||
return ProxyState{
|
||||
@@ -263,20 +286,27 @@ func (s *ProxyService) emitState() {
|
||||
|
||||
// ShutdownForQuit 用于处理与 ShutdownForQuit 相关的逻辑。
|
||||
func (s *ProxyService) ShutdownForQuit() {
|
||||
s.lifecycleMu.Lock()
|
||||
defer s.lifecycleMu.Unlock()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
var finalErr error
|
||||
|
||||
if s.proxy != nil {
|
||||
if err := s.proxy.Stop(ctx); err != nil && !errors.Is(err, context.Canceled) {
|
||||
if s.proxyServer() != nil {
|
||||
if err := s.proxyServer().Stop(ctx); err != nil && !errors.Is(err, context.Canceled) {
|
||||
finalErr = err
|
||||
}
|
||||
}
|
||||
if err := s.ClearCursorSettings(); err != nil {
|
||||
finalErr = errors.Join(finalErr, err)
|
||||
s.mu.RLock()
|
||||
applied := s.cursorSettingsApplied
|
||||
s.mu.RUnlock()
|
||||
if applied {
|
||||
if err := s.ClearCursorSettings(); err != nil {
|
||||
finalErr = errors.Join(finalErr, err)
|
||||
}
|
||||
}
|
||||
if s.backendHost != nil {
|
||||
if err := s.backendHost.Stop(ctx); err != nil && !errors.Is(err, context.Canceled) {
|
||||
if s.backend() != nil {
|
||||
if err := s.backend().Stop(ctx); err != nil && !errors.Is(err, context.Canceled) {
|
||||
finalErr = errors.Join(finalErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
33
internal/client/lifecycle_race_test.go
Normal file
33
internal/client/lifecycle_race_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
serverconfig "cursor/internal/backend/server/config"
|
||||
"cursor/internal/certs"
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStatePollingDuringProxyInitialization(t *testing.T) {
|
||||
ca, err := certs.LoadOrCreateLocalCA(t.TempDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
service := &ProxyService{certManager: ca}
|
||||
cfg := serverconfig.DefaultConfig()
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for range 300 {
|
||||
_ = service.GetState()
|
||||
}
|
||||
}()
|
||||
for i := range 30 {
|
||||
cfg.ProxyListenAddr = fmt.Sprintf("127.0.0.1:%d", 30000+i)
|
||||
if err := service.ensureProxy(cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
@@ -9,7 +9,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cursor/internal/logger"
|
||||
"cursor/internal/modelchannel"
|
||||
"cursor/internal/netproxy"
|
||||
)
|
||||
|
||||
// RemoteModel 表示从模型服务 /models 端点拉取到的一个模型。
|
||||
@@ -33,6 +35,7 @@ func (s *ProxyService) ListRemoteModels(adapterType string, baseURL string, apiK
|
||||
adapterType = strings.ToLower(strings.TrimSpace(adapterType))
|
||||
baseURL = strings.TrimSpace(baseURL)
|
||||
apiKey = strings.TrimSpace(apiKey)
|
||||
logger.RegisterSecrets(apiKey)
|
||||
if adapterType != "openai" && adapterType != "anthropic" {
|
||||
return result, fmt.Errorf("模型类型仅支持 openai 或 anthropic")
|
||||
}
|
||||
@@ -63,7 +66,7 @@ func (s *ProxyService) ListRemoteModels(adapterType string, baseURL string, apiK
|
||||
}
|
||||
request.Header.Set("Accept", "application/json")
|
||||
|
||||
response, err := http.DefaultClient.Do(request)
|
||||
response, err := netproxy.CredentialSafeClient(http.DefaultClient).Do(request)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("请求模型列表失败: %w", err)
|
||||
}
|
||||
|
||||
@@ -73,4 +73,4 @@ func TestBuildModelsEndpointDefaults(t *testing.T) {
|
||||
if !strings.HasPrefix(buildModelsEndpoint("openai", "https://example.com/v1"), "https://example.com/v1/") {
|
||||
t.Fatalf("/v1 结尾去重后应保留原路径前缀")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ func (s *ProxyService) runtimeConfigSnapshot(_ context.Context) (localruntime.Ru
|
||||
if s == nil {
|
||||
return localruntime.RuntimeConfigSnapshot{}, nil
|
||||
}
|
||||
if s.backendHost != nil && s.backendHost.ConfigManager() != nil {
|
||||
return s.backendHost.ConfigManager().LegacyRuntimeSnapshot(context.Background())
|
||||
if s.backend() != nil && s.backend().ConfigManager() != nil {
|
||||
return s.backend().ConfigManager().LegacyRuntimeSnapshot(context.Background())
|
||||
}
|
||||
if s.store == nil {
|
||||
return localruntime.RuntimeConfigSnapshot{}, nil
|
||||
|
||||
@@ -29,6 +29,7 @@ const (
|
||||
|
||||
// ProxyService 定义了当前模块中的 ProxyService 类型。
|
||||
type ProxyService struct {
|
||||
lifecycleMu sync.Mutex
|
||||
// proxy 表示 IDE 版 MITM 代理。
|
||||
proxy *mitm.ProxyServer
|
||||
// certManager 用于在代理监听地址变化时重建 MITM 服务,同时为 CLI HTTPS 监听器签发证书。
|
||||
@@ -98,34 +99,44 @@ func (s *ProxyService) ensureBackendHost() error {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
if s.backendHost != nil {
|
||||
s.configMu.Lock()
|
||||
defer s.configMu.Unlock()
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
if s.backend() != nil {
|
||||
return nil
|
||||
}
|
||||
host, err := backend.NewHost(s.store, s.certManager)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.backendHost = host
|
||||
s.setBackend(host)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ProxyService) ensureProxy(cfg serverconfig.Config) error {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
s.configMu.Lock()
|
||||
defer s.configMu.Unlock()
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
baseURL := ""
|
||||
if s.backendHost != nil {
|
||||
baseURL = s.backendHost.BaseURL()
|
||||
if s.backend() != nil {
|
||||
baseURL = s.backend().BaseURL()
|
||||
}
|
||||
if baseURL == "" {
|
||||
baseURL = "http://" + cfg.BackendListenAddr
|
||||
}
|
||||
listenAddr := cfg.ProxyListenAddr
|
||||
|
||||
if s.proxy != nil {
|
||||
snapshot := s.proxy.Snapshot()
|
||||
if s.proxyServer() != nil {
|
||||
snapshot := s.proxyServer().Snapshot()
|
||||
if snapshot.ListenAddr == listenAddr {
|
||||
return s.proxy.UpdateBaseURL(baseURL)
|
||||
return s.proxyServer().UpdateBaseURL(baseURL)
|
||||
}
|
||||
if snapshot.Running {
|
||||
return fmt.Errorf("代理正在运行,不能从 %s 切换到 %s,请先停止服务", snapshot.ListenAddr, listenAddr)
|
||||
@@ -136,12 +147,12 @@ func (s *ProxyService) ensureProxy(cfg serverconfig.Config) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.proxy = proxyServer
|
||||
s.setProxy(proxyServer)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ProxyService) waitForBackend(ctx context.Context) error {
|
||||
if s == nil || s.backendHost == nil {
|
||||
if s == nil || s.backend() == nil {
|
||||
return nil
|
||||
}
|
||||
ticker := time.NewTicker(backendHealthCheckInterval)
|
||||
@@ -149,7 +160,7 @@ func (s *ProxyService) waitForBackend(ctx context.Context) error {
|
||||
var lastErr error
|
||||
for {
|
||||
healthCtx, healthCancel := context.WithTimeout(ctx, backendHealthCheckAttemptTimeout)
|
||||
err := s.backendHost.HealthCheck(healthCtx)
|
||||
err := s.backend().HealthCheck(healthCtx)
|
||||
healthCancel()
|
||||
if err == nil {
|
||||
return nil
|
||||
@@ -165,3 +176,24 @@ func (s *ProxyService) waitForBackend(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ProxyService) backend() *backend.Host {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.backendHost
|
||||
}
|
||||
func (s *ProxyService) proxyServer() *mitm.ProxyServer {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.proxy
|
||||
}
|
||||
func (s *ProxyService) setBackend(host *backend.Host) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.backendHost = host
|
||||
}
|
||||
func (s *ProxyService) setProxy(proxy *mitm.ProxyServer) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.proxy = proxy
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user