feat: add miner management endpoints and standardize all API paths to /api/v1 prefix
- Add POST /api/v1/miners/{miner_id}/jobs endpoint for listing miner-assigned jobs with filtering
- Add POST /api/v1/miners/{miner_id}/earnings endpoint for miner earnings tracking (mock implementation)
- Add PUT /api/v1/miners/{miner_id}/capabilities endpoint for updating miner capabilities
- Add DELETE /api/v1/miners/{miner_id} endpoint for miner deregistration (sets OFFLINE status)
- Add JobService.fail_job()
This commit is contained in:
@@ -72,6 +72,17 @@ class JobService:
|
||||
|
||||
return self.session.execute(query).scalars().all()
|
||||
|
||||
def fail_job(self, job_id: str, miner_id: str, error_message: str) -> Job:
|
||||
"""Mark a job as failed"""
|
||||
job = self.get_job(job_id)
|
||||
job.state = JobState.FAILED
|
||||
job.error = error_message
|
||||
job.assigned_miner_id = miner_id
|
||||
self.session.add(job)
|
||||
self.session.commit()
|
||||
self.session.refresh(job)
|
||||
return job
|
||||
|
||||
def cancel_job(self, job: Job) -> Job:
|
||||
if job.state not in {JobState.queued, JobState.running}:
|
||||
return job
|
||||
|
||||
@@ -116,3 +116,15 @@ class MinerService:
|
||||
def online_count(self) -> int:
|
||||
result = self.session.execute(select(Miner).where(Miner.status == "ONLINE"))
|
||||
return len(result.all())
|
||||
|
||||
def deregister(self, miner_id: str) -> None:
|
||||
"""Deregister a miner from the system"""
|
||||
miner = self.session.get(Miner, miner_id)
|
||||
if miner is None:
|
||||
raise KeyError("miner not registered")
|
||||
|
||||
# Set status to OFFLINE instead of deleting to maintain history
|
||||
miner.status = "OFFLINE"
|
||||
miner.session_token = None
|
||||
self.session.add(miner)
|
||||
self.session.commit()
|
||||
|
||||
Reference in New Issue
Block a user