Phase 1: Extract Domain Types ============================= - Create internal/domain/ package with canonical types: - domain/task.go: Task, Attempt structs - domain/tracking.go: TrackingConfig and MLflow/TensorBoard/Wandb configs - domain/dataset.go: DatasetSpec - domain/status.go: JobStatus constants - domain/errors.go: FailureClass system with classification functions - domain/doc.go: package documentation - Update queue/task.go to re-export domain types (backward compatibility) - Update TUI model/state.go to use domain types via type aliases - Simplify TUI services: remove ~60 lines of conversion functions Phase 2: Delete ErrorCategory System ==================================== - Remove deprecated ErrorCategory type and constants - Remove TaskError struct and related functions - Remove mapping functions: ClassifyError, IsRetryable, GetUserMessage, RetryDelay - Update all queue implementations to use domain.FailureClass directly: - queue/metrics.go: RecordTaskFailure/Retry now take FailureClass - queue/queue.go: RetryTask uses domain.ClassifyFailure - queue/filesystem_queue.go: RetryTask and MoveToDeadLetterQueue updated - queue/sqlite_queue.go: RetryTask and MoveToDeadLetterQueue updated Lines eliminated: ~190 lines of conversion and mapping code Result: Single source of truth for domain types and error classification
71 lines
3.4 KiB
Go
71 lines
3.4 KiB
Go
// Package domain provides core domain types for fetch_ml.
|
|
// These types have zero internal dependencies and are used across all packages.
|
|
package domain
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// Task represents an ML experiment task
|
|
type Task struct {
|
|
ID string `json:"id"`
|
|
JobName string `json:"job_name"`
|
|
Args string `json:"args"`
|
|
Status string `json:"status"` // queued, running, completed, failed
|
|
Priority int64 `json:"priority"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
StartedAt *time.Time `json:"started_at,omitempty"`
|
|
EndedAt *time.Time `json:"ended_at,omitempty"`
|
|
WorkerID string `json:"worker_id,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
Output string `json:"output,omitempty"`
|
|
// TODO(phase1): SnapshotID is an opaque identifier only.
|
|
// TODO(phase2): Resolve SnapshotID and verify its checksum/digest before execution.
|
|
SnapshotID string `json:"snapshot_id,omitempty"`
|
|
// DatasetSpecs is the preferred structured dataset input and should be authoritative.
|
|
DatasetSpecs []DatasetSpec `json:"dataset_specs,omitempty"`
|
|
// Datasets is kept for backward compatibility (legacy callers).
|
|
Datasets []string `json:"datasets,omitempty"`
|
|
Metadata map[string]string `json:"metadata,omitempty"`
|
|
|
|
// Resource requests (optional, 0 means unspecified)
|
|
CPU int `json:"cpu,omitempty"`
|
|
MemoryGB int `json:"memory_gb,omitempty"`
|
|
GPU int `json:"gpu,omitempty"`
|
|
GPUMemory string `json:"gpu_memory,omitempty"`
|
|
|
|
// User ownership and permissions
|
|
UserID string `json:"user_id"` // User who owns this task
|
|
Username string `json:"username"` // Username for display
|
|
CreatedBy string `json:"created_by"` // User who submitted the task
|
|
|
|
// Lease management for task resilience
|
|
LeaseExpiry *time.Time `json:"lease_expiry,omitempty"` // When task lease expires
|
|
LeasedBy string `json:"leased_by,omitempty"` // Worker ID holding lease
|
|
|
|
// Retry management
|
|
RetryCount int `json:"retry_count"` // Number of retry attempts made
|
|
MaxRetries int `json:"max_retries"` // Maximum retry limit (default 3)
|
|
LastError string `json:"last_error,omitempty"` // Last error encountered
|
|
NextRetry *time.Time `json:"next_retry,omitempty"` // When to retry next (exponential backoff)
|
|
|
|
// Attempt tracking - complete history of all execution attempts
|
|
Attempts []Attempt `json:"attempts,omitempty"`
|
|
|
|
// Optional tracking configuration for this task
|
|
Tracking *TrackingConfig `json:"tracking,omitempty"`
|
|
}
|
|
|
|
// Attempt represents a single execution attempt of a task
|
|
type Attempt struct {
|
|
Attempt int `json:"attempt"` // Attempt number (1-indexed)
|
|
StartedAt time.Time `json:"started_at"` // When attempt started
|
|
EndedAt *time.Time `json:"ended_at,omitempty"` // When attempt ended (if completed)
|
|
WorkerID string `json:"worker_id,omitempty"` // Which worker ran this attempt
|
|
Status string `json:"status"` // running, completed, failed
|
|
FailureClass FailureClass `json:"failure_class,omitempty"` // Failure classification (if failed)
|
|
ExitCode int `json:"exit_code,omitempty"` // Process exit code
|
|
Signal string `json:"signal,omitempty"` // Termination signal (if any)
|
|
Error string `json:"error,omitempty"` // Error message (if failed)
|
|
LogTail string `json:"log_tail,omitempty"` // Last N lines of log output
|
|
}
|