Local
This commit is contained in:
+76
-17
@@ -83,12 +83,39 @@ post '/api/v1/video' => sub {
|
||||
|
||||
get '/api/v1/tasks' => sub {
|
||||
my $status = query_parameters->get("status") || 'PENDING';
|
||||
my $sth = database->prepare("SELECT id, video_id, status FROM tasks WHERE status=? ORDER BY id");
|
||||
$sth->execute($status);
|
||||
my $type = query_parameters->get("type");
|
||||
|
||||
unless ($type) {
|
||||
send_error("Missing 'type' query parameter", 400);
|
||||
}
|
||||
|
||||
# Optional pagination
|
||||
my $page = query_parameters->get("page") || 1;
|
||||
my $per_page = query_parameters->get("per_page") || 20;
|
||||
my $offset = ($page - 1) * $per_page;
|
||||
|
||||
my $sth = database->prepare(
|
||||
"SELECT id, video_id, task_type AS type, status FROM tasks WHERE status=? AND task_type=? ORDER BY id LIMIT ? OFFSET ?"
|
||||
);
|
||||
$sth->execute($status, $type, $per_page, $offset);
|
||||
my $ref = $sth->fetchall_hashref('id');
|
||||
$sth->finish();
|
||||
|
||||
return $ref;
|
||||
# Total count for pagination metadata
|
||||
my $count_sth = database->prepare(
|
||||
"SELECT COUNT(*) AS cnt FROM tasks WHERE status=? AND task_type=?"
|
||||
);
|
||||
$count_sth->execute($status, $type);
|
||||
my $cnt = ($count_sth->fetchrow_hashref() || { cnt => 0 })->{cnt};
|
||||
$count_sth->finish();
|
||||
|
||||
return {
|
||||
tasks => $ref,
|
||||
page => $page,
|
||||
per_page => $per_page,
|
||||
total => $cnt,
|
||||
total_pages => max(1, int(($cnt + $per_page - 1) / $per_page)),
|
||||
};
|
||||
};
|
||||
|
||||
get '/api/v1/task/:task' => sub {
|
||||
@@ -129,7 +156,7 @@ get '/api/v1/nexttask/:type' => sub {
|
||||
};
|
||||
|
||||
post '/api/v1/task/:task/complete' => sub {
|
||||
my $task = route_parameters->get("task");
|
||||
my $task_id = route_parameters->get("task");
|
||||
|
||||
# Accept both JSON body and form-encoded data for assign_key/results.
|
||||
my ($assign_key, $results);
|
||||
@@ -143,24 +170,31 @@ post '/api/v1/task/:task/complete' => sub {
|
||||
$results = body_parameters->get("results");
|
||||
}
|
||||
|
||||
unless ($assign_key) {
|
||||
send_error("Missing assign_key", 400);
|
||||
}
|
||||
# Optional worker verification: if assign_key is provided, require IN_PROGRESS + matching key.
|
||||
# When omitted (e.g., UI-driven workflows), skip worker checks and just complete the task.
|
||||
if ($assign_key) {
|
||||
my $sth = database->prepare("SELECT * FROM tasks WHERE id=? AND assign_key=? AND status='IN_PROGRESS'");
|
||||
$sth->execute($task_id, $assign_key);
|
||||
my $ref = $sth->fetchrow_hashref();
|
||||
$sth->finish();
|
||||
|
||||
# Verify the task is assigned to the worker
|
||||
my $sth = database->prepare("SELECT * FROM tasks WHERE id=? AND assign_key=? AND status='IN_PROGRESS'");
|
||||
$sth->execute($task, $assign_key);
|
||||
my $ref = $sth->fetchrow_hashref();
|
||||
$sth->finish();
|
||||
|
||||
unless(ref $ref) {
|
||||
send_error("Task not assigned to this worker or not in progress", 403);
|
||||
unless(ref $ref) {
|
||||
send_error("Task not assigned to this worker or not in progress", 403);
|
||||
}
|
||||
} else {
|
||||
# No assign_key provided — caller may be an unauthenticated UI, etc.
|
||||
my $sth = database->prepare("SELECT id FROM tasks WHERE id=?");
|
||||
$sth->execute($task_id);
|
||||
unless ($sth->fetchrow_hashref()) {
|
||||
send_error("Task not found", 404);
|
||||
}
|
||||
$sth->finish();
|
||||
}
|
||||
|
||||
# Update the task as completed (store results as JSON text for MariaDB)
|
||||
my $results_json = defined $results ? encode_json($results) : 'null';
|
||||
my $update_sth = database->prepare("UPDATE tasks SET status='COMPLETED', results=?, updated_at=NOW() WHERE id=?");
|
||||
$update_sth->execute($results_json, $task);
|
||||
$update_sth->execute($results_json, $task_id);
|
||||
if($update_sth->rows == 0) {
|
||||
send_error("Failed to complete task", 500);
|
||||
}
|
||||
@@ -183,4 +217,29 @@ post '/api/v1/task' => sub {
|
||||
return { id => $task_id };
|
||||
};
|
||||
|
||||
start();
|
||||
post '/api/v1/task/:task/unassign' => sub {
|
||||
my $task_id = route_parameters->get("task");
|
||||
|
||||
my $update_sth = database->prepare(
|
||||
"UPDATE tasks SET status='PENDING', assign_key=NULL, assigned_at=NULL, updated_at=NOW() WHERE id=?"
|
||||
);
|
||||
$update_sth->execute($task_id);
|
||||
|
||||
if ($update_sth->rows == 0) {
|
||||
send_error("Task not found or already in PENDING state", 404);
|
||||
}
|
||||
|
||||
|
||||
return { message => 'Task unassigned' };
|
||||
};
|
||||
|
||||
start();
|
||||
|
||||
|
||||
sub max {
|
||||
return (sort { $b <=> $a } @_)[0];
|
||||
}
|
||||
|
||||
sub min {
|
||||
return (sort { $a <=> $b } @_)[0];
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@ plugins:
|
||||
dbi_params:
|
||||
RaiseError: 1
|
||||
AutoCommit: 1
|
||||
on_connect_do: ["SET NAMES 'utf8'", "SET CHARACTER SET 'utf8'" ]
|
||||
on_connect_do: ["SET NAMES 'utf8mb4'", "SET CHARACTER SET 'utf8mb4'" ]
|
||||
log_queries: 1
|
||||
|
||||
server:
|
||||
|
||||
Reference in New Issue
Block a user