3636logger = logging .getLogger (__name__ )
3737
3838MAX_JOB_NOPID = timedelta (seconds = 10 )
39+ MAX_TASK_WAIT = 10
3940
4041
4142def method_validate (
@@ -479,7 +480,7 @@ def tomato_job() -> None:
479480
480481
481482def job_thread (
482- tasks : list ,
483+ tasks : list [ Task ] ,
483484 component : Component ,
484485 device : Device ,
485486 driver : Driver ,
@@ -518,23 +519,26 @@ def job_thread(
518519 taskid += f":{ task .task_name !r} "
519520 thread .current_task = task
520521 logger .info ("%s: processing task" , taskid )
522+
523+ # Hold while start contidions are not met
521524 while True :
522- time .sleep (1e-1 )
523525 if task .start_with_task_name is None :
524- pass
526+ break
525527 elif task .start_with_task_name in thread .started_task_names :
526- pass
528+ break
527529 else :
528530 logger .debug (
529531 "%s: waiting for task_name '%s'" , taskid , task .start_with_task_name
530532 )
531- continue
533+ time .sleep (0.1 )
534+
535+ # Hold while component task_list is not ready
536+ while True :
532537 logger .debug (
533538 "%s: polling component %s for task readiness" , taskid , component .name
534539 )
535- ret , req = lpp .comm (
536- req , dict (cmd = "task_status" , params = {** kwargs }), ** lppargs
537- )
540+ msg = dict (cmd = "task_status" , params = {** kwargs })
541+ ret , req = lpp .comm (req , msg , ** lppargs )
538542 if ret .success and ret .data ["can_submit" ]:
539543 break
540544 elif req .closed :
@@ -543,18 +547,56 @@ def job_thread(
543547 logger .warning (
544548 "%s: cannot submit onto component %s, waiting" , taskid , component .name
545549 )
550+ time .sleep (0.1 )
546551
552+ # Send task to component
547553 logger .info ("%s: sending task to component %s" , taskid , component .name )
554+ t0 = time .perf_counter ()
548555 msg = dict (cmd = "task_start" , params = {"task" : task , ** kwargs })
549556 ret , req = lpp .comm (req , msg , ** lppargs )
550557 if req .closed :
551558 thread .crashed = True
552559 sys .exit ()
553560
554- t0 = time .perf_counter ()
561+ # Wait until the correct task is running, or MAX_TASK_WAIT
562+ while True :
563+ dt = time .perf_counter () - t0
564+ msg = dict (cmd = "task_status" , params = {** kwargs })
565+ ret , req = lpp .comm (req , msg , ** lppargs )
566+ if req .closed :
567+ thread .crashed = True
568+ sys .exit ()
569+ elif ret .success and ret .data ["running" ] is False :
570+ logger .warning (
571+ "%s: task submitted %f s ago but not yet running" , taskid , dt
572+ )
573+ pass
574+ elif ret .success and "task" in ret .data and ret .data ["task" ] != task :
575+ logger .warning (
576+ "%s: task submitted %f s ago but other task running: %s" ,
577+ taskid ,
578+ dt ,
579+ ret .data ["task" ],
580+ )
581+ pass
582+ elif ret .success and "task" in ret .data and ret .data ["task" ] == task :
583+ break
584+ elif ret .success and "task" not in ret .data :
585+ break
586+ if dt > MAX_TASK_WAIT :
587+ logger .critical ("%s: task was submitted, but is not executed, aborting" )
588+ thread .crashed = True
589+ sys .exit ()
590+ time .sleep (0.1 )
591+ logger .info ("%s: correct task running on component %s" , taskid , component .role )
592+
593+ # Main task loop
594+ tP = time .perf_counter ()
555595 while True :
556596 tN = time .perf_counter ()
557- if tN - t0 > device .pollrate :
597+
598+ # Poll for data every device.pollrate, save to pickle
599+ if tN - tP > device .pollrate :
558600 logger .debug ("%s: polling task for data" , taskid )
559601 msg = dict (cmd = "task_data" , params = {** kwargs })
560602 ret , req = lpp .comm (req , msg , ** lppargs , timeout = 5000 )
@@ -566,8 +608,9 @@ def job_thread(
566608 ds : xr .Dataset = ret .data
567609 ds .attrs ["tomato_Component" ] = component .model_dump_json ()
568610 data_to_pickle (ds , datapath , role = component .role )
569- t0 += device .pollrate
611+ tP += device .pollrate
570612
613+ # Poll for completion and correct task status
571614 logger .debug ("%s: polling task for completion" , taskid )
572615 msg = dict (cmd = "task_status" , params = {** kwargs })
573616 ret , req = lpp .comm (req , msg , ** lppargs )
@@ -577,10 +620,16 @@ def job_thread(
577620 elif ret .success and not ret .data ["running" ]:
578621 logger .info ("%s: task no longer running, break" , taskid )
579622 break
623+ elif ret .success and "task" in ret .data and ret .data ["task" ] != task :
624+ logger .critical ("%s: wront task running, break" , taskid )
625+ logger .debug ("%s: expected task: %s" , taskid , task )
626+ logger .debug ("%s: executed task: %s" , taskid , ret .data ["task" ])
627+ break
580628 elif ret .success is False :
581629 logger .critical (f"{ ret = } " )
582630 break
583631
632+ # Stop task if stop trigger condition met, save to pickle
584633 if (
585634 task .stop_with_task_name is not None
586635 and task .stop_with_task_name in thread .started_task_names
@@ -598,7 +647,9 @@ def job_thread(
598647 data_to_pickle (ds , datapath , role = component .role )
599648 break
600649
601- time .sleep (max (1e-1 , (device .pollrate - (tN - t0 )) / 2 ))
650+ time .sleep (max (1e-1 , (device .pollrate - (tN - tP )) / 2 ))
651+
652+ # Store final task data, housekeeping.
602653 logger .info ("%s: task fetching final data" , taskid )
603654 msg = dict (cmd = "task_data" , params = {** kwargs })
604655 ret , req = lpp .comm (req , msg , ** lppargs , timeout = 5000 )
@@ -613,6 +664,7 @@ def job_thread(
613664 thread .completed_tasks .append (task )
614665 thread .current_task = None
615666
667+ # Reset component at the end of the job
616668 logger .info (
617669 "%s: all tasks done on component %s, resetting" , component .role , component .name
618670 )
@@ -705,10 +757,10 @@ def job_main_loop(
705757 started_task_names = set ()
706758 while True :
707759 tN = time .perf_counter ()
708- if snapshot is not None and tN - t0 > snapshot .frequency :
760+ if snapshot is not None and tN - t0 > snapshot .snapshot_interval :
709761 logger .debug ("creating snapshot" )
710762 merge_netcdfs (job , snapshot = True )
711- t0 += snapshot .frequency
763+ t0 += snapshot .snapshot_interval
712764
713765 # Collect and push task names
714766 for t in threads .values ():
0 commit comments