Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion internal/service/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,13 @@ func (o *Orchestrator) startServicesInParallel(ctx context.Context, serviceNames
if len(containerID) > 12 {
containerID = containerID[:12]
}
spinner.Success(fmt.Sprintf("Started %s %s", ui.Bold(serviceName), ui.Dim(containerID)))

// Show the appropriate message based on whether it was already running
if svc.WasAlreadyRunning() {
spinner.Success(fmt.Sprintf("%s already running %s", ui.Bold(serviceName), ui.Dim(containerID)))
} else {
spinner.Success(fmt.Sprintf("Started %s %s", ui.Bold(serviceName), ui.Dim(containerID)))
}

// Track successfully started service (protected by mutex)
mu.Lock()
Expand Down
36 changes: 27 additions & 9 deletions internal/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@ type Service struct {
Config config.Service // Service configuration from ork.yml

// Runtime state
state State // Current service state
healthStatus HealthStatus // Current health status
containerID string // Docker container ID (when running)
networkID string // Network ID the service is connected to
startedAt time.Time // When the service was started
stoppedAt time.Time // When the service was stopped
lastError error // Last error encountered
state State // Current service state
healthStatus HealthStatus // Current health status
containerID string // Docker container ID (when running)
networkID string // Network ID the service is connected to
startedAt time.Time // When the service was started
stoppedAt time.Time // When the service was stopped
lastError error // Last error encountered
wasAlreadyRunning bool // True if the container was found already running (not newly started)

// Synchronization
mu sync.RWMutex // Protects state changes
Expand Down Expand Up @@ -95,6 +96,7 @@ func (s *Service) Start(ctx context.Context, client *docker.Client, networkID st
s.state = StateStarting
s.healthStatus = HealthStarting
s.lastError = nil
s.wasAlreadyRunning = false // Reset flag - assume we'll start a new container

// Check if a container already exists
if err := s.checkAndCleanupExistingContainer(ctx, client); err != nil {
Expand All @@ -103,6 +105,12 @@ func (s *Service) Start(ctx context.Context, client *docker.Client, networkID st
return err
}

// If the service is already running (discovered by checkAndCleanupExistingContainer),
// return success without trying to start a new container
if s.state == StateRunning {
return nil
}

// Load environment variables
envVars, err := config.LoadAllEnvForService(s.Name, s.Config.Env)
if err != nil {
Expand Down Expand Up @@ -252,6 +260,13 @@ func (s *Service) IsHealthy() bool {
return s.GetHealthStatus() == HealthHealthy
}

// WasAlreadyRunning returns true if the service was found already running (not newly started)
func (s *Service) WasAlreadyRunning() bool {
s.mu.RLock()
defer s.mu.RUnlock()
return s.wasAlreadyRunning
}

// ============================================================================
// Health Check Methods
// ============================================================================
Expand Down Expand Up @@ -371,10 +386,13 @@ func (s *Service) checkAndCleanupExistingContainer(ctx context.Context, client *
if container.Labels["ork.service"] == s.Name {
// Check if it's running
if strings.HasPrefix(container.Status, "Up") {
// Update our state to match reality
// Update our state to match reality - service is already running
s.containerID = container.ID
s.state = StateRunning
return fmt.Errorf("service %s is already running (container: %s)", s.Name, container.ID)
s.startedAt = time.Now() // Approximate start time
s.wasAlreadyRunning = true // Mark as already running (not newly started)
// Return nil (success) - the service is already in the desired state
return nil
}

// Container exists but is stopped - remove it
Expand Down
Loading