From 57ee94f42296a189c35a3b3176ce2310c44088f1 Mon Sep 17 00:00:00 2001 From: henryruhs Date: Sun, 13 Sep 2026 10:52:20 +0200 Subject: [PATCH] prevent queries when one already exist --- facefusion/apis/endpoints/jobs.py | 30 ++++++++++++++++++--- facefusion/apis/locales.py | 4 +-- tests/test_api_jobs.py | 44 +++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/facefusion/apis/endpoints/jobs.py b/facefusion/apis/endpoints/jobs.py index 45a0df82..b3980530 100644 --- a/facefusion/apis/endpoints/jobs.py +++ b/facefusion/apis/endpoints/jobs.py @@ -4,7 +4,7 @@ from functools import partial from starlette.background import BackgroundTask, BackgroundTasks from starlette.requests import Request from starlette.responses import JSONResponse -from starlette.status import HTTP_200_OK, HTTP_201_CREATED, HTTP_202_ACCEPTED, HTTP_400_BAD_REQUEST, HTTP_404_NOT_FOUND +from starlette.status import HTTP_200_OK, HTTP_201_CREATED, HTTP_202_ACCEPTED, HTTP_400_BAD_REQUEST, HTTP_404_NOT_FOUND, HTTP_409_CONFLICT import facefusion.choices import facefusion.core @@ -69,6 +69,12 @@ async def update_jobs(request : Request) -> JSONResponse: action = request.query_params.get('action') if action == 'submit': + if job_manager.find_job_ids('queued'): + return JSONResponse( + { + 'message': translator.get('job_all_not_submitted', 'facefusion.apis') + }, status_code = HTTP_409_CONFLICT) + if job_manager.submit_jobs(state_manager.get_item('halt_on_error')): return JSONResponse( { @@ -91,10 +97,16 @@ async def update_jobs(request : Request) -> JSONResponse: return JSONResponse( { - 'message': translator.get('job_all_not_run', 'facefusion.apis') + 'message': translator.get('job_all_not_started', 'facefusion.apis') }, status_code = HTTP_400_BAD_REQUEST) if action == 'retry': + if job_manager.find_job_ids('queued'): + return JSONResponse( + { + 'message': translator.get('job_all_not_retried', 'facefusion.apis') + }, status_code = HTTP_409_CONFLICT) + if job_manager.find_job_ids('failed'): retry_jobs_task = BackgroundTask(partial(job_runner.retry_jobs, facefusion.core.process_step, state_manager.get_item('halt_on_error'))) @@ -119,6 +131,12 @@ async def update_job(request : Request) -> JSONResponse: action = request.query_params.get('action') if action == 'submit': + if job_manager.find_job_ids('queued'): + return JSONResponse( + { + 'message': translator.get('job_not_submitted', 'facefusion.apis') + }, status_code = HTTP_409_CONFLICT) + if job_manager.submit_job(job_id): return JSONResponse( { @@ -143,10 +161,16 @@ async def update_job(request : Request) -> JSONResponse: return JSONResponse( { - 'message': translator.get('job_not_run', 'facefusion.apis') + 'message': translator.get('job_not_started', 'facefusion.apis') }, status_code = HTTP_400_BAD_REQUEST) if action == 'retry': + if job_manager.find_job_ids('queued'): + return JSONResponse( + { + 'message': translator.get('job_not_retried', 'facefusion.apis') + }, status_code = HTTP_409_CONFLICT) + if job_id in job_manager.find_job_ids('failed'): retry_job_tasks = BackgroundTasks() retry_job_tasks.add_task(partial(job_runner.retry_job, job_id, facefusion.core.process_step)) diff --git a/facefusion/apis/locales.py b/facefusion/apis/locales.py index bcd546f2..13e626e9 100644 --- a/facefusion/apis/locales.py +++ b/facefusion/apis/locales.py @@ -18,11 +18,11 @@ LOCALES : Locales =\ 'job_not_created': 'job not created', 'job_not_submitted': 'job not submitted', 'job_not_deleted': 'job not deleted', - 'job_not_run': 'job not run', + 'job_not_started': 'job not started', 'job_not_retried': 'job not retried', 'job_all_not_submitted': 'jobs not submitted', 'job_all_not_deleted': 'jobs not deleted', - 'job_all_not_run': 'jobs not run', + 'job_all_not_started': 'jobs not started', 'job_all_not_retried': 'jobs not retried', 'job_step_not_added': 'step not added', 'job_step_not_inserted': 'step not inserted', diff --git a/tests/test_api_jobs.py b/tests/test_api_jobs.py index a527b828..8f724383 100644 --- a/tests/test_api_jobs.py +++ b/tests/test_api_jobs.py @@ -247,6 +247,15 @@ def test_submit_jobs(test_client : TestClient) -> None: assert find_job_ids('queued') == [ 'job-test-submit-jobs' ] assert submit_jobs_response.status_code == 200 + submit_jobs_response = test_client.patch('/jobs?action=submit', headers = + { + 'Authorization': 'Bearer ' + access_token + }) + submit_jobs_body = submit_jobs_response.json() + + assert submit_jobs_body.get('message') == 'jobs not submitted' + assert submit_jobs_response.status_code == 409 + def test_submit_job(test_client : TestClient) -> None: submit_job_response = test_client.patch('/jobs/job-test-submit-job?action=submit') @@ -300,6 +309,15 @@ def test_submit_job(test_client : TestClient) -> None: assert find_job_ids('queued') == [ 'job-test-submit-job' ] assert submit_job_response.status_code == 200 + submit_job_response = test_client.patch('/jobs/job-test-submit-job?action=submit', headers = + { + 'Authorization': 'Bearer ' + access_token + }) + submit_job_body = submit_job_response.json() + + assert submit_job_body.get('message') == 'job not submitted' + assert submit_job_response.status_code == 409 + def test_run_jobs(test_client : TestClient) -> None: run_jobs_response = test_client.patch('/jobs?action=run') @@ -321,7 +339,7 @@ def test_run_jobs(test_client : TestClient) -> None: }) run_jobs_body = run_jobs_response.json() - assert run_jobs_body.get('message') == 'jobs not run' + assert run_jobs_body.get('message') == 'jobs not started' assert run_jobs_response.status_code == 400 create_job('job-test-run-jobs') @@ -371,7 +389,7 @@ def test_run_job(test_client : TestClient) -> None: }) run_job_body = run_job_response.json() - assert run_job_body.get('message') == 'job not run' + assert run_job_body.get('message') == 'job not started' assert run_job_response.status_code == 400 test_client.post('/jobs/job-test-run-job?action=add', headers = @@ -447,6 +465,17 @@ def test_retry_jobs(test_client : TestClient) -> None: assert retry_jobs_response.status_code == 202 assert retry_jobs_mock.called is True + create_job('job-test-retry-jobs-queued') + move_job_file('job-test-retry-jobs-queued', 'queued') + retry_jobs_response = test_client.patch('/jobs?action=retry', headers = + { + 'Authorization': 'Bearer ' + access_token + }) + retry_jobs_body = retry_jobs_response.json() + + assert retry_jobs_body.get('message') == 'jobs not retried' + assert retry_jobs_response.status_code == 409 + def test_retry_job(test_client : TestClient) -> None: retry_job_response = test_client.patch('/jobs/job-test-retry-job?action=retry') @@ -497,6 +526,17 @@ def test_retry_job(test_client : TestClient) -> None: assert retry_job_response.status_code == 202 assert retry_job_mock.called is True + create_job('job-test-retry-job-queued') + move_job_file('job-test-retry-job-queued', 'queued') + retry_job_response = test_client.patch('/jobs/job-test-retry-job?action=retry', headers = + { + 'Authorization': 'Bearer ' + access_token + }) + retry_job_body = retry_job_response.json() + + assert retry_job_body.get('message') == 'job not retried' + assert retry_job_response.status_code == 409 + def test_delete_jobs(test_client : TestClient) -> None: delete_jobs_response = test_client.delete('/jobs')