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
23 changes: 23 additions & 0 deletions crates/farm-controller/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ impl AppScheduler {
}
}

fn list_task_attempt_logs(
&self,
task_id: TaskId,
attempt_id: uuid::Uuid,
) -> Result<Vec<FarmLogEntry>, FarmError> {
match self {
Self::Memory(scheduler) => scheduler.list_task_attempt_logs(task_id, attempt_id),
Self::Sqlite(scheduler) => scheduler.list_task_attempt_logs(task_id, attempt_id),
}
}

fn record_worker_logs(
&self,
worker_id: WorkerId,
Expand Down Expand Up @@ -272,6 +283,10 @@ fn app(scheduler: AppScheduler) -> Router {
.route("/v1/tasks/{task_id}/started", post(mark_task_started))
.route("/v1/tasks/{task_id}/renew", post(renew_task_lease))
.route("/v1/tasks/{task_id}/complete", post(complete_task))
.route(
"/v1/tasks/{task_id}/attempts/{attempt_id}/logs",
get(list_task_attempt_logs),
)
.route(
"/v1/tasks/{task_id}/artifacts/{artifact_index}",
get(download_task_artifact),
Expand Down Expand Up @@ -383,6 +398,13 @@ async fn list_worker_logs(
Ok(Json(scheduler.list_worker_logs(worker_id)?))
}

async fn list_task_attempt_logs(
State(scheduler): State<AppScheduler>,
Path((task_id, attempt_id)): Path<(TaskId, uuid::Uuid)>,
) -> Result<Json<Vec<FarmLogEntry>>, ApiError> {
Ok(Json(scheduler.list_task_attempt_logs(task_id, attempt_id)?))
}

async fn record_worker_logs(
State(scheduler): State<AppScheduler>,
Path(worker_id): Path<WorkerId>,
Expand Down Expand Up @@ -486,6 +508,7 @@ impl From<FarmError> for ApiError {
| FarmError::TaskNotFound(_)
| FarmError::WorkerNotFound(_)
| FarmError::ArtifactNotFound { .. } => StatusCode::NOT_FOUND,
FarmError::AttemptNotFound { .. } => StatusCode::NOT_FOUND,
FarmError::InvalidSubmission(_) => StatusCode::BAD_REQUEST,
FarmError::InvalidLease | FarmError::InvalidState(_) => StatusCode::CONFLICT,
FarmError::LockPoisoned | FarmError::Storage(_) => StatusCode::INTERNAL_SERVER_ERROR,
Expand Down
43 changes: 43 additions & 0 deletions crates/farm-core/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,8 @@ pub struct Task {
pub stdout_tail: Option<String>,
pub stderr_tail: Option<String>,
#[serde(default)]
pub attempt_records: Vec<TaskAttempt>,
#[serde(default)]
pub artifact_paths: Vec<PathBuf>,
#[serde(default)]
pub artifacts: Vec<TaskArtifact>,
Expand All @@ -502,6 +504,41 @@ pub struct TaskArtifact {
pub modified_at: Option<DateTime<Utc>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskAttempt {
pub id: Uuid,
pub number: u32,
pub worker_id: WorkerId,
pub state: TaskAttemptState,
pub leased_at: DateTime<Utc>,
#[serde(default)]
pub started_at: Option<DateTime<Utc>>,
#[serde(default)]
pub completed_at: Option<DateTime<Utc>>,
#[serde(default)]
pub exit_code: Option<i32>,
#[serde(default)]
pub stdout_tail: Option<String>,
#[serde(default)]
pub stderr_tail: Option<String>,
#[serde(default)]
pub failure_summary: Option<String>,
pub log_ref: String,
#[serde(default)]
pub artifacts: Vec<TaskArtifact>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum TaskAttemptState {
Leased,
Running,
Succeeded,
Failed,
Cancelled,
Expired,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ArtifactKind {
Expand Down Expand Up @@ -580,6 +617,8 @@ pub struct WorkerLogInput {
pub job_id: Option<JobId>,
#[serde(default)]
pub task_id: Option<TaskId>,
#[serde(default)]
pub attempt_id: Option<Uuid>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -596,6 +635,8 @@ pub struct FarmLogEntry {
#[serde(default)]
pub task_id: Option<TaskId>,
#[serde(default)]
pub attempt_id: Option<Uuid>,
#[serde(default)]
pub worker_id: Option<WorkerId>,
}

Expand Down Expand Up @@ -641,6 +682,8 @@ pub enum WorkerState {
pub struct TaskLeaseInfo {
pub token: String,
pub worker_id: WorkerId,
#[serde(default)]
pub attempt_id: Uuid,
pub leased_at: DateTime<Utc>,
pub expires_at: DateTime<Utc>,
}
Expand Down
Loading
Loading