@@ -816,6 +816,28 @@ async def init(
816816 else :
817817 return await cls ._init (address , session_id , new = new , timeout = timeout )
818818
819+ async def _update_progress (self , task_id : str , progress : Progress ):
820+ zero_acc_time = 0
821+ delay = 0.5
822+ while True :
823+ try :
824+ last_progress_value = progress .value
825+ progress .value = await self ._task_api .get_task_progress (task_id )
826+ if abs (progress .value - last_progress_value ) < 1e-4 :
827+ # if percentage does not change, we add delay time by 0.5 seconds every time
828+ zero_acc_time = min (5 , zero_acc_time + 0.5 )
829+ delay = zero_acc_time
830+ else :
831+ # percentage changes, we use percentage speed to calc progress time
832+ zero_acc_time = 0
833+ speed = abs (progress .value - last_progress_value ) / delay
834+ # one percent for one second
835+ delay = 0.01 / speed
836+ delay = max (0.5 , min (delay , 5.0 ))
837+ await asyncio .sleep (delay )
838+ except asyncio .CancelledError :
839+ break
840+
819841 async def _run_in_background (
820842 self ,
821843 tileables : list ,
@@ -826,55 +848,52 @@ async def _run_in_background(
826848 with enter_mode (build = True , kernel = True ):
827849 # wait for task to finish
828850 cancelled = False
851+ progress_task = asyncio .create_task (
852+ self ._update_progress (task_id , progress )
853+ )
829854 start_time = time .time ()
830- while True :
831- try :
832- if not cancelled :
833- task_result : Union [TaskResult , None ] = None
834- try :
835- task_result = await self ._task_api .wait_task (
836- task_id , timeout = 0.5
837- )
838- finally :
839- if task_result is None :
840- # not finished, set progress
841- progress .value = await self ._task_api .get_task_progress (
842- task_id
843- )
844- else :
845- progress .value = 1.0
846- if task_result is not None :
847- break
848- else :
849- # wait for task to finish
850- task_result : TaskResult = await self ._task_api .wait_task (
851- task_id
852- )
855+ task_result : Optional [TaskResult ] = None
856+ try :
857+ if self .timeout is None :
858+ check_interval = 30
859+ else :
860+ elapsed = time .time () - start_time
861+ check_interval = min (self .timeout - elapsed , 30 )
862+
863+ while True :
864+ task_result = await self ._task_api .wait_task (
865+ task_id , timeout = check_interval
866+ )
867+ if task_result is not None :
853868 break
854- except asyncio .CancelledError :
855- # cancelled
856- cancelled = True
857- await self ._task_api .cancel_task (task_id )
858- except TimeoutError : # pragma: no cover
859- # ignore timeout when waiting for subtask progresses
860- pass
861- finally :
862- if (
869+ elif (
863870 self .timeout is not None
864871 and time .time () - start_time > self .timeout
865872 ):
866873 raise TimeoutError (
867874 f"Task({ task_id } ) running time > { self .timeout } "
868875 )
869- profiling .result = task_result .profiling
870- if task_result .profiling :
871- logger .warning (
872- "Profile task %s execution result:\n %s" ,
873- task_id ,
874- json .dumps (task_result .profiling , indent = 4 ),
875- )
876- if task_result .error :
877- raise task_result .error .with_traceback (task_result .traceback )
876+ except asyncio .CancelledError :
877+ # cancelled
878+ cancelled = True
879+ await self ._task_api .cancel_task (task_id )
880+ finally :
881+ progress_task .cancel ()
882+ if task_result is not None :
883+ progress .value = 1.0
884+ else :
885+ # not finished, set progress
886+ progress .value = await self ._task_api .get_task_progress (task_id )
887+ if task_result is not None :
888+ profiling .result = task_result .profiling
889+ if task_result .profiling :
890+ logger .warning (
891+ "Profile task %s execution result:\n %s" ,
892+ task_id ,
893+ json .dumps (task_result .profiling , indent = 4 ),
894+ )
895+ if task_result .error :
896+ raise task_result .error .with_traceback (task_result .traceback )
878897 if cancelled :
879898 return
880899 fetch_tileables = await self ._task_api .get_fetch_tileables (task_id )
0 commit comments