92 lines
2.2 KiB
Python
92 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import asdict, dataclass, field
|
|
from datetime import datetime, timezone
|
|
from enum import Enum
|
|
from typing import Any, Dict, Optional
|
|
|
|
|
|
def utc_now() -> str:
|
|
return datetime.now(timezone.utc).astimezone().isoformat(timespec="seconds")
|
|
|
|
|
|
class WorkerStatus(str, Enum):
|
|
ONLINE = "online"
|
|
OFFLINE = "offline"
|
|
BUSY = "busy"
|
|
|
|
|
|
class JobStatus(str, Enum):
|
|
PENDING = "pending"
|
|
RUNNING = "running"
|
|
COMPLETED = "completed"
|
|
FAILED = "failed"
|
|
CANCELLED = "cancelled"
|
|
|
|
|
|
@dataclass
|
|
class Worker:
|
|
id: str
|
|
hostname: str = ""
|
|
max_concurrent: int = 1
|
|
status: str = WorkerStatus.ONLINE.value
|
|
last_heartbeat: str = field(default_factory=utc_now)
|
|
current_job_id: Optional[str] = None
|
|
|
|
def to_dict(self) -> dict:
|
|
return asdict(self)
|
|
|
|
|
|
@dataclass
|
|
class Job:
|
|
id: str
|
|
worker_id: Optional[str]
|
|
status: str = JobStatus.PENDING.value
|
|
title: str = ""
|
|
excel_key: str = ""
|
|
downloads_prefix: str = ""
|
|
original_filename: str = ""
|
|
cancel_requested: bool = False
|
|
result: Dict[str, Any] = field(default_factory=dict)
|
|
error: Optional[str] = None
|
|
created_at: str = field(default_factory=utc_now)
|
|
started_at: Optional[str] = None
|
|
finished_at: Optional[str] = None
|
|
job_id: Optional[str] = None
|
|
task_id: Optional[str] = None
|
|
parent_download_job_id: Optional[str] = None
|
|
shard_index: Optional[int] = None
|
|
shard_count: Optional[int] = None
|
|
|
|
def to_dict(self) -> dict:
|
|
return asdict(self)
|
|
|
|
@property
|
|
def is_distributed_parent(self) -> bool:
|
|
return (
|
|
self.parent_download_job_id is None
|
|
and self.shard_count is not None
|
|
and int(self.shard_count) > 1
|
|
)
|
|
|
|
@property
|
|
def is_shard(self) -> bool:
|
|
return bool(self.parent_download_job_id)
|
|
|
|
|
|
@dataclass
|
|
class JobEventRecord:
|
|
id: int
|
|
job_id: str
|
|
event_type: str
|
|
message: str
|
|
timestamp: str
|
|
radicado: Optional[str] = None
|
|
nit: Optional[str] = None
|
|
index: Optional[int] = None
|
|
total: Optional[int] = None
|
|
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
|
|
def to_dict(self) -> dict:
|
|
return asdict(self)
|