| 1324 | } |
| 1325 | |
| 1326 | static void application_job_recover(cbm_daemon_application_job_t *job, |
| 1327 | application_job_execution_t *execution) { |
| 1328 | if (application_job_cancel_requested(job)) { |
| 1329 | application_job_execution_cancel(execution); |
| 1330 | return; |
| 1331 | } |
| 1332 | char marker_path[APPLICATION_PATH_CAP] = {0}; |
| 1333 | char quarantine_path[APPLICATION_PATH_CAP] = {0}; |
| 1334 | if (!application_recovery_files_create(marker_path, quarantine_path)) { |
| 1335 | return; |
| 1336 | } |
| 1337 | |
| 1338 | int quarantined = 0; |
| 1339 | char **previous_suspects = NULL; |
| 1340 | int previous_count = 0; |
| 1341 | int recovery_cap = application_max_restarts(); |
| 1342 | for (int recovery_index = 0; recovery_index < recovery_cap; recovery_index++) { |
| 1343 | if (application_job_cancel_requested(job)) { |
| 1344 | application_job_execution_cancel(execution); |
| 1345 | break; |
| 1346 | } |
| 1347 | if (!application_truncate_file(marker_path)) { |
| 1348 | break; |
| 1349 | } |
| 1350 | application_attempt_t attempt; |
| 1351 | application_attempt_status_t status = |
| 1352 | application_job_run_attempt(job, marker_path, quarantine_path, &attempt); |
| 1353 | if (status == APPLICATION_ATTEMPT_CANCELLED) { |
| 1354 | application_job_execution_cancel(execution); |
| 1355 | break; |
| 1356 | } |
| 1357 | if (status != APPLICATION_ATTEMPT_TERMINAL) { |
| 1358 | break; |
| 1359 | } |
| 1360 | cbm_proc_outcome_t failure_outcome = CBM_PROC_SPAWN_FAILED; |
| 1361 | application_attempt_decision_t decision = |
| 1362 | application_consume_attempt(job, &attempt, execution, &failure_outcome); |
| 1363 | if (decision != APPLICATION_ATTEMPT_DECISION_RECOVERABLE || |
| 1364 | !application_recovery_record_suspects( |
| 1365 | job, marker_path, quarantine_path, failure_outcome, recovery_index, |
| 1366 | &previous_suspects, &previous_count, &quarantined, execution)) { |
| 1367 | break; |
| 1368 | } |
| 1369 | } |
| 1370 | application_free_suspects(previous_suspects, previous_count); |
| 1371 | if (!execution->response && !execution->unsafe_terminal && quarantined > 0) { |
| 1372 | application_job_try_partial(job, quarantine_path, quarantined, execution); |
| 1373 | } |
| 1374 | application_recovery_files_remove(marker_path, quarantine_path); |
| 1375 | } |
| 1376 | |
| 1377 | /* A capacity/cancellation conflict is resolved by the terminal publication |
| 1378 | * that freed the project or global slot. Admit waiting session auto-index work |
no test coverage detected