async def jobs_dispatcher(): if Worker.select().count() == 0: for i in range(1): Worker.create(state="available") workers = Worker.select().where(Worker.state == "available") # no available workers, wait if workers.count() == 0: return with db.atomic('IMMEDIATE'): jobs = Job.select().where(Job.state == "scheduled") # no jobs to process, wait if jobs.count() == 0: await asyncio.sleep(3) return for i in range(min(workers.count(), jobs.count())): job = jobs[i] worker = workers[i] job.state = "running" job.started_time = datetime.now() job.save() worker.state = "busy" worker.save() jobs_in_memory_state[job.id] = { "worker": worker.id, "task": asyncio.ensure_future(run_job(worker, job)), }
async def api_stop_job(request, job_id): # TODO auth or some kind job = Job.select().where(Job.id == job_id) if job.count() == 0: raise NotFound(f"Error: no job with the id '{job_id}'") job = job[0] api_logger.info(f"Request to stop job '{job.name}' [{job.id}]") if job.state == "scheduled": api_logger.info(f"Cancel scheduled job '{job.name}' [job.id] " f"on request") job.state = "canceled" job.save() await broadcast({ "action": "update_job", "data": model_to_dict(job), }, ["jobs", f"job-{job.id}", f"app-jobs-{job.url_or_path}"]) return response.text("ok") if job.state == "running": api_logger.info(f"Cancel running job '{job.name}' [job.id] on request") job.state = "canceled" job.end_time = datetime.now() job.save() jobs_in_memory_state[job.id]["task"].cancel() worker = Worker.select().where( Worker.id == jobs_in_memory_state[job.id]["worker"])[0] worker.state = "available" worker.save() await broadcast({ "action": "update_job", "data": model_to_dict(job), }, ["jobs", f"job-{job.id}", f"app-jobs-{job.url_or_path}"]) return response.text("ok") if job.state in ("done", "canceled", "failure", "error"): api_logger.info(f"Request to cancel job '{job.name}' " f"[job.id] but job is already in '{job.state}' state, " f"do nothing") # nothing to do, task is already done return response.text("ok") raise Exception(f"Tryed to cancel a job with an unknown state: " f"{job.state}")