33 lines
903 B
Go
33 lines
903 B
Go
|
|
package usecase
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
|
||
|
|
"apps/backend/internal/module/scout/domain"
|
||
|
|
)
|
||
|
|
|
||
|
|
// StartRun guards queued → running and is idempotent for a retry of the same
|
||
|
|
// job. A different job can never take over an active or terminal run.
|
||
|
|
func (s *Service) StartRun(ctx context.Context, ownerUID int64, runID, jobID string) (*domain.Run, error) {
|
||
|
|
if s == nil || s.Repo == nil || runID == "" || jobID == "" {
|
||
|
|
return nil, domain.ErrValidation
|
||
|
|
}
|
||
|
|
run, err := s.Repo.GetRun(ctx, ownerUID, runID)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
if run.JobID != jobID {
|
||
|
|
return nil, domain.ErrIllegalRunStatus
|
||
|
|
}
|
||
|
|
if run.Status == domain.RunRunning {
|
||
|
|
return run, nil
|
||
|
|
}
|
||
|
|
if err := run.Transition(domain.RunRunning, domain.NowNano()); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
if err := s.Repo.ReplaceRunGuarded(ctx, ownerUID, runID, []string{domain.RunQueued}, run); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return run, nil
|
||
|
|
}
|