diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go index 63774f1..e6f9843 100644 --- a/pkg/instance/instance.go +++ b/pkg/instance/instance.go @@ -14,18 +14,6 @@ import ( "time" ) -// TimeProvider interface allows for testing with mock time -type TimeProvider interface { - Now() time.Time -} - -// realTimeProvider implements TimeProvider using the actual time -type realTimeProvider struct{} - -func (realTimeProvider) Now() time.Time { - return time.Now() -} - // Process represents a running instance of the llama server type Process struct { Name string `json:"name"` @@ -58,9 +46,6 @@ type Process struct { // Restart control restartCancel context.CancelFunc `json:"-"` // Cancel function for pending restarts monitorDone chan struct{} `json:"-"` // Channel to signal monitor goroutine completion - - // Time provider for testing (kept for backward compatibility during refactor) - timeProvider TimeProvider `json:"-"` // Time provider for testing } // NewInstance creates a new instance with the given name, log path, and options @@ -77,7 +62,6 @@ func NewInstance(name string, globalBackendSettings *config.BackendConfig, globa globalInstanceSettings: globalInstanceSettings, globalBackendSettings: globalBackendSettings, logger: logger, - timeProvider: realTimeProvider{}, Created: time.Now().Unix(), Status: Stopped, onStatusChange: onStatusChange, @@ -160,8 +144,8 @@ func (i *Process) SetOptions(options *CreateInstanceOptions) { } // SetTimeProvider sets a custom time provider for testing +// Delegates to the Proxy component func (i *Process) SetTimeProvider(tp TimeProvider) { - i.timeProvider = tp if i.proxy != nil { i.proxy.SetTimeProvider(tp) } @@ -233,9 +217,6 @@ func (i *Process) UnmarshalJSON(data []byte) error { } // Initialize fields that are not serialized - if i.timeProvider == nil { - i.timeProvider = realTimeProvider{} - } if i.logger == nil && i.globalInstanceSettings != nil { i.logger = NewInstanceLogger(i.Name, i.globalInstanceSettings.LogsDir) } @@ -260,3 +241,40 @@ func (i *Process) IsRemote() bool { func (i *Process) GetLogs(num_lines int) (string, error) { return i.logger.GetLogs(num_lines) } + +// getBackendHostPort extracts the host and port from instance options +// Returns the configured host and port for the backend +func (i *Process) getBackendHostPort() (string, int) { + i.mu.RLock() + defer i.mu.RUnlock() + + if i.options == nil { + return "localhost", 0 + } + + var host string + var port int + switch i.options.BackendType { + case backends.BackendTypeLlamaCpp: + if i.options.LlamaServerOptions != nil { + host = i.options.LlamaServerOptions.Host + port = i.options.LlamaServerOptions.Port + } + case backends.BackendTypeMlxLm: + if i.options.MlxServerOptions != nil { + host = i.options.MlxServerOptions.Host + port = i.options.MlxServerOptions.Port + } + case backends.BackendTypeVllm: + if i.options.VllmServerOptions != nil { + host = i.options.VllmServerOptions.Host + port = i.options.VllmServerOptions.Port + } + } + + if host == "" { + host = "localhost" + } + + return host, port +} diff --git a/pkg/instance/lifecycle.go b/pkg/instance/lifecycle.go index dfdeab3..d530900 100644 --- a/pkg/instance/lifecycle.go +++ b/pkg/instance/lifecycle.go @@ -179,35 +179,8 @@ func (i *Process) WaitForHealthy(timeout int) error { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) defer cancel() - // Get instance options to build the health check URL - opts := i.GetOptions() - if opts == nil { - return fmt.Errorf("instance %s has no options set", i.Name) - } - - // Build the health check URL directly - var host string - var port int - switch opts.BackendType { - case backends.BackendTypeLlamaCpp: - if opts.LlamaServerOptions != nil { - host = opts.LlamaServerOptions.Host - port = opts.LlamaServerOptions.Port - } - case backends.BackendTypeMlxLm: - if opts.MlxServerOptions != nil { - host = opts.MlxServerOptions.Host - port = opts.MlxServerOptions.Port - } - case backends.BackendTypeVllm: - if opts.VllmServerOptions != nil { - host = opts.VllmServerOptions.Host - port = opts.VllmServerOptions.Port - } - } - if host == "" { - host = "localhost" - } + // Get host/port from process + host, port := i.getBackendHostPort() healthURL := fmt.Sprintf("http://%s:%d/health", host, port) // Create a dedicated HTTP client for health checks diff --git a/pkg/instance/proxy.go b/pkg/instance/proxy.go index 5727edb..d8a7462 100644 --- a/pkg/instance/proxy.go +++ b/pkg/instance/proxy.go @@ -8,8 +8,21 @@ import ( "net/url" "sync" "sync/atomic" + "time" ) +// TimeProvider interface allows for testing with mock time +type TimeProvider interface { + Now() time.Time +} + +// realTimeProvider implements TimeProvider using the actual time +type realTimeProvider struct{} + +func (realTimeProvider) Now() time.Time { + return time.Now() +} + // Proxy manages HTTP reverse proxy and request tracking for an instance. type Proxy struct { process *Process // Owner reference - Proxy is owned by Process @@ -54,30 +67,8 @@ func (p *Proxy) buildProxy() (*httputil.ReverseProxy, error) { return nil, fmt.Errorf("instance %s is a remote instance and should not use local proxy", p.process.Name) } - // Get host/port from options - var host string - var port int - switch options.BackendType { - case backends.BackendTypeLlamaCpp: - if options.LlamaServerOptions != nil { - host = options.LlamaServerOptions.Host - port = options.LlamaServerOptions.Port - } - case backends.BackendTypeMlxLm: - if options.MlxServerOptions != nil { - host = options.MlxServerOptions.Host - port = options.MlxServerOptions.Port - } - case backends.BackendTypeVllm: - if options.VllmServerOptions != nil { - host = options.VllmServerOptions.Host - port = options.VllmServerOptions.Port - } - } - - if host == "" { - host = "localhost" - } + // Get host/port from process + host, port := p.process.getBackendHostPort() targetURL, err := url.Parse(fmt.Sprintf("http://%s:%d", host, port)) if err != nil {