[ 
https://issues.apache.org/jira/browse/FINERACT-2926?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Adam Saghy resolved FINERACT-2926.
----------------------------------
    Resolution: Fixed

> StuckJobListener waits forever when a COB partition was killed
> --------------------------------------------------------------
>
>                 Key: FINERACT-2926
>                 URL: https://issues.apache.org/jira/browse/FINERACT-2926
>             Project: Apache Fineract
>          Issue Type: Bug
>            Reporter: Arnold Galovics
>            Assignee: Arnold Galovics
>            Priority: Major
>             Fix For: 1.16.0
>
>
> 🐛 Steps to Reproduce
> 1. Run Fineract 1.15.0 with batch manager and batch worker enabled in one 
> container, business date enabled, and 2 loans lagging behind the COB date.
> 2. Start Loan COB with POST /jobs/\{id}?command=executeJob.
> 3. Kill the container (docker kill) while the COB partition step is STARTED.
> 4. Start the container again and read the application log and the 
> batch_job_execution and batch_step_execution tables.
>  
> ❌ Actual Result
> • The job execution stays STARTED/UNKNOWN and the partition step stays 
> STARTED forever.
> • StuckJobListener logs "Sleeping for a second to wait for the partitions to 
> complete for job <id>" in an endless loop and never restarts the job. 
> Readiness is not blocked.
> • Boot resets job.currently_running, but the execution is never closed.
> • Marking the partition FAILED does not help: the loop exits only on 
> COMPLETED.
>  
> ✅ Expected Result
> • A partition step that has not been updated for longer than a timeout 
> (proposed: fineract.job.stuck-partition-timeout, default 10m) is marked 
> FAILED, so the job is restarted and re-runs only the unfinished partitions. 
> COMPLETED partitions are not re-run.
> • No endless loop, and one stuck tenant does not block stuck-job recovery for 
> the tenants after it.
>  
> ℹ️ Notes
> • Observed on Fineract 1.15.0, Docker, Postgres 16, single-instance topology. 
> Not tested: multi-instance topology.
> • Workaround: set the STARTED step and job executions to ABANDONED and 
> reboot. ABANDONED only closes the execution; it cannot be restarted.
> • is_suspended is deliberately not honoured: restarting a stuck job is crash 
> recovery, not a scheduled run.
>  
> 🔧 Technical Notes
> • StuckJobListener.java:17-45. 
> StuckJobExecutorServiceImpl#waitUntilAllPartitionsFinished loops on 
> JobExecutionRepository#getNotCompletedPartitionsCount, which counts every 
> non-partitioner step with STATUS <> COMPLETED, so FAILED, STOPPED and 
> ABANDONED worker steps also loop forever. The listener runs on an event 
> thread and handles tenants one after another.
> • Fix: count only STARTING, STARTED and STOPPING steps; in each loop 
> iteration run an UPDATE setting such steps to FAILED (EXIT_CODE FAILED, 
> END_TIME now) where LAST_UPDATED is older than now minus the timeout. The 
> existing updateJobStatusToFailed and restart then re-run only FAILED 
> partitions (SimpleStepExecutionSplitter#shouldStart restarts only FAILED and 
> STOPPED, which is why ABANDONED is not the target state).
> • A live worker updates LAST_UPDATED on every chunk commit, so it is not 
> marked dead. The timeout must exceed the slowest chunk. LAST_UPDATED is 
> written in the JVM time zone, so pods with mixed time zones would break the 
> cutoff.
> • Test: StuckJobExecutorServiceImplTest (Mockito): count 1 then 0 calls the 
> stale update with the right cutoff, then updateJobStatusToFailed, then 
> restart; count 0 goes straight to restart.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to