@@ -1014,7 +1014,10 @@ def stream_reader(response_stream: Any = response_stream) -> None:
10141014 self ._execute_orchestrator ,
10151015 _on_outcome_uncertain = response_stream .cancel ,
10161016 ),
1017- self ._cancel_orchestrator ,
1017+ partial (
1018+ self ._cancel_orchestrator ,
1019+ _on_outcome_uncertain = response_stream .cancel ,
1020+ ),
10181021 work_item .orchestratorRequest ,
10191022 stub ,
10201023 work_item .completionToken ,
@@ -1173,6 +1176,7 @@ def _execute_orchestrator(
11731176 stub .CompleteOrchestratorTask (res )
11741177 except BaseException as error :
11751178 recovery_error : BaseException | None = None
1179+ outcome_uncertain = outcome_attempted
11761180 self ._logger .error (
11771181 f"Orchestrator dispatch for '{ req .instanceId } ' exited without a confirmed outcome." ,
11781182 exc_info = True ,
@@ -1182,33 +1186,35 @@ def _execute_orchestrator(
11821186 self ._cancel_orchestrator (req , stub , completionToken )
11831187 except BaseException as abandonment_error :
11841188 recovery_error = abandonment_error
1185- outcome_attempted = True
1186- self ._logger .error (
1187- f"Failed to abandon orchestrator dispatch for '{ req .instanceId } '." ,
1188- exc_info = True ,
1189- )
1189+ outcome_uncertain = True
11901190 # A failed RPC may already have been accepted. Do not retry it or
11911191 # send a conflicting outcome; release ownership through its stream.
1192- if outcome_attempted and _on_outcome_uncertain is not None :
1193- self ._logger .error (
1194- f"Resetting the owning work-item stream for '{ req .instanceId } ' after an uncertain outcome."
1195- )
1192+ if outcome_uncertain and _on_outcome_uncertain is not None :
11961193 try :
1197- _on_outcome_uncertain ( )
1194+ self . _reset_orchestrator_stream ( req . instanceId , _on_outcome_uncertain )
11981195 except BaseException as reset_error :
11991196 if recovery_error is None or (
12001197 isinstance (recovery_error , Exception ) and not isinstance (reset_error , Exception )
12011198 ):
12021199 recovery_error = reset_error
1203- self ._logger .error (
1204- f"Failed to reset the owning work-item stream for '{ req .instanceId } '." ,
1205- exc_info = True ,
1206- )
12071200 if not isinstance (error , Exception ):
12081201 raise
12091202 if recovery_error is not None and not isinstance (recovery_error , Exception ):
12101203 raise recovery_error
12111204
1205+ def _reset_orchestrator_stream (self , instance_id : str , reset : Callable [[], Any ]) -> None :
1206+ self ._logger .error (
1207+ f"Resetting the owning work-item stream for '{ instance_id } ' after an uncertain outcome."
1208+ )
1209+ try :
1210+ reset ()
1211+ except BaseException :
1212+ self ._logger .error (
1213+ f"Failed to reset the owning work-item stream for '{ instance_id } '." ,
1214+ exc_info = True ,
1215+ )
1216+ raise
1217+
12121218 def _get_orchestrator_response (
12131219 self ,
12141220 req : pb .OrchestratorRequest ,
@@ -1351,12 +1357,27 @@ def _cancel_orchestrator(
13511357 req : pb .OrchestratorRequest ,
13521358 stub : Any ,
13531359 completionToken : Any ,
1360+ * ,
1361+ _on_outcome_uncertain : Callable [[], Any ] | None = None ,
13541362 ) -> None :
1355- stub .AbandonTaskOrchestratorWorkItem (
1356- pb .AbandonOrchestrationTaskRequest (
1357- completionToken = completionToken
1363+ try :
1364+ stub .AbandonTaskOrchestratorWorkItem (
1365+ pb .AbandonOrchestrationTaskRequest (
1366+ completionToken = completionToken
1367+ )
13581368 )
1359- )
1369+ except BaseException as error :
1370+ self ._logger .error (
1371+ f"Failed to abandon orchestrator dispatch for '{ req .instanceId } '." ,
1372+ exc_info = True ,
1373+ )
1374+ if _on_outcome_uncertain is not None :
1375+ try :
1376+ self ._reset_orchestrator_stream (req .instanceId , _on_outcome_uncertain )
1377+ except BaseException as reset_error :
1378+ if isinstance (error , Exception ) and not isinstance (reset_error , Exception ):
1379+ raise
1380+ raise
13601381 self ._logger .info (f"Cancelled orchestration task for invocation ID: { req .instanceId } " )
13611382
13621383 def _on_activity_execution_started (self , req : pb .ActivityRequest ) -> None :
0 commit comments