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
30 changes: 10 additions & 20 deletions src/nexus/cli/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,40 +165,30 @@ def add_job(job_request: dict, target_name: str | None = None) -> dict:
return response.json()


@handle_api_errors
def kill_running_jobs(job_ids: list[str], target_name: str | None = None) -> dict:
results = {"killed": [], "failed": []}
def _process_job_batch(job_ids: list[str], method: str, endpoint_suffix: str, success_key: str, target_name: str | None) -> dict:
results = {success_key: [], "failed": []}
api_url = get_api_base_url(target_name)

request_fn = requests.post if method == "POST" else requests.delete
for job_id in job_ids:
try:
response = requests.post(f"{api_url}/jobs/{job_id}/kill")
response = request_fn(f"{api_url}/jobs/{job_id}{endpoint_suffix}")
if response.status_code == 204:
results["killed"].append(job_id)
results[success_key].append(job_id)
else:
response.raise_for_status()
except Exception as e:
results["failed"].append({"id": job_id, "error": str(e)})

return results


@handle_api_errors
def remove_queued_jobs(job_ids: list[str], target_name: str | None = None) -> dict:
results = {"removed": [], "failed": []}
api_url = get_api_base_url(target_name)
def kill_running_jobs(job_ids: list[str], target_name: str | None = None) -> dict:
return _process_job_batch(job_ids, "POST", "/kill", "killed", target_name)

for job_id in job_ids:
try:
response = requests.delete(f"{api_url}/jobs/{job_id}")
if response.status_code == 204:
results["removed"].append(job_id)
else:
response.raise_for_status()
except Exception as e:
results["failed"].append({"id": job_id, "error": str(e)})

return results
@handle_api_errors
def remove_queued_jobs(job_ids: list[str], target_name: str | None = None) -> dict:
return _process_job_batch(job_ids, "DELETE", "", "removed", target_name)


@handle_api_errors
Expand Down
18 changes: 18 additions & 0 deletions src/nexus/cli/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
STATUS_QUEUED = "queued"
STATUS_RUNNING = "running"
STATUS_COMPLETED = "completed"
STATUS_FAILED = "failed"
STATUS_KILLED = "killed"

TERMINAL_STATUSES: frozenset[str] = frozenset([STATUS_COMPLETED, STATUS_FAILED, STATUS_KILLED])

JOB_INIT_MAX_ATTEMPTS = 10
COMPLETED_JOB_LOG_TAIL_LINES = 5000
HISTORY_MAX_DISPLAY = 25
COMMAND_TRUNCATE_DEFAULT = 80
COMMAND_TRUNCATE_SHORT = 50
COMMAND_TRUNCATE_QUEUE = 60
ATTACH_LOG_TAIL_LINES = 1000
QUEUE_PREVIEW_COUNT = 3
PING_THRESHOLD_GOOD = 50
PING_THRESHOLD_WARNING = 100
15 changes: 15 additions & 0 deletions src/nexus/cli/ids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import hashlib
import os
import time

import base58

__all__ = ["generate_job_id"]


def generate_job_id() -> str:
timestamp = str(time.time()).encode()
random_bytes = os.urandom(4)
hash_input = timestamp + random_bytes
hash_bytes = hashlib.sha256(hash_input).digest()[:4]
return base58.b58encode(hash_bytes).decode()[:6].lower()
Loading
Loading