2020from dispatch .coroutine import AllDirective , AnyDirective , AnyException , RaceDirective
2121from dispatch .error import IncompatibleStateError
2222from dispatch .experimental .durable .function import DurableCoroutine , DurableGenerator
23- from dispatch .proto import Call , Error , Input , Output
23+ from dispatch .proto import Call , Error , Input , Output , TailCall
2424from dispatch .status import Status
2525
2626logger = logging .getLogger (__name__ )
@@ -37,6 +37,8 @@ class CoroutineResult:
3737 coroutine_id : CoroutineID
3838 value : Optional [Any ] = None
3939 error : Optional [Exception ] = None
40+ call : Optional [Call ] = None
41+ status : Status = Status .OK
4042
4143
4244@dataclass
@@ -438,6 +440,10 @@ def _run(self, input: Input) -> Output:
438440 coroutine_result : Optional [CoroutineResult ] = None
439441 try :
440442 coroutine_yield = coroutine .run ()
443+ except TailCall as tc :
444+ coroutine_result = CoroutineResult (
445+ coroutine_id = coroutine .id , call = tc .call , status = tc .status
446+ )
441447 except StopIteration as e :
442448 coroutine_result = CoroutineResult (
443449 coroutine_id = coroutine .id , value = e .value
@@ -450,7 +456,11 @@ def _run(self, input: Input) -> Output:
450456
451457 # Handle coroutines that return or raise.
452458 if coroutine_result is not None :
453- if coroutine_result .error is not None :
459+ if coroutine_result .call is not None :
460+ logger .debug (
461+ "%s reset to %s" , coroutine , coroutine_result .call .function
462+ )
463+ elif coroutine_result .error is not None :
454464 logger .debug ("%s raised %s" , coroutine , coroutine_result .error )
455465 else :
456466 logger .debug ("%s returned %s" , coroutine , coroutine_result .value )
@@ -463,6 +473,11 @@ def _run(self, input: Input) -> Output:
463473 return Output .error (
464474 Error .from_exception (coroutine_result .error )
465475 )
476+ if coroutine_result .call is not None :
477+ return Output .tail_call (
478+ tail_call = coroutine_result .call ,
479+ status = coroutine_result .status ,
480+ )
466481 return Output .value (coroutine_result .value )
467482
468483 # Otherwise, notify the parent of the result.
0 commit comments