1111
1212namespace Temporal \Internal \Activity ;
1313
14+ use Temporal \Activity \ActivityCancellationDetails ;
1415use Temporal \Activity \ActivityContextInterface ;
1516use Temporal \Activity \ActivityInfo ;
1617use Temporal \DataConverter \DataConverterInterface ;
1920use Temporal \DataConverter \ValuesInterface ;
2021use Temporal \Exception \Client \ActivityCanceledException ;
2122use Temporal \Exception \Client \ActivityCompletionException ;
23+ use Temporal \Exception \Client \ActivityPausedException ;
2224use Temporal \Exception \Client \ServiceClientException ;
2325use Temporal \Interceptor \HeaderInterface ;
2426use Temporal \Internal \Interceptor \HeaderCarrier ;
@@ -31,26 +33,17 @@ final class ActivityContext implements ActivityContextInterface, HeaderCarrier
3133 private ActivityInfo $ info ;
3234
3335 private bool $ doNotCompleteOnReturn = false ;
34- private RPCConnectionInterface $ rpc ;
35- private DataConverterInterface $ converter ;
36- private ?ValuesInterface $ heartbeatDetails ;
37- private ValuesInterface $ input ;
38- private HeaderInterface $ header ;
3936 private ?\WeakReference $ instance = null ;
37+ private ?ActivityCancellationDetails $ cancellationDetails = null ;
4038
4139 public function __construct (
42- RPCConnectionInterface $ rpc ,
43- DataConverterInterface $ converter ,
44- ValuesInterface $ input ,
45- HeaderInterface $ header ,
46- ?ValuesInterface $ lastHeartbeatDetails = null ,
40+ private readonly RPCConnectionInterface $ rpc ,
41+ private readonly DataConverterInterface $ converter ,
42+ private ValuesInterface $ input ,
43+ private HeaderInterface $ header ,
44+ private readonly ?ValuesInterface $ lastHeartbeatDetails = null ,
4745 ) {
4846 $ this ->info = new ActivityInfo ();
49- $ this ->rpc = $ rpc ;
50- $ this ->converter = $ converter ;
51- $ this ->heartbeatDetails = $ lastHeartbeatDetails ;
52- $ this ->input = $ input ;
53- $ this ->header = $ header ;
5447 }
5548
5649 public function getInfo (): ActivityInfo
@@ -91,20 +84,19 @@ public function getDataConverter(): DataConverterInterface
9184
9285 public function hasHeartbeatDetails (): bool
9386 {
94- return $ this ->heartbeatDetails !== null ;
87+ return $ this ->lastHeartbeatDetails !== null ;
9588 }
9689
9790 /**
9891 * @param Type|string $type
99- * @return mixed
10092 */
101- public function getHeartbeatDetails ($ type = null )
93+ public function getLastHeartbeatDetails ($ type = null ): mixed
10294 {
10395 if (!$ this ->hasHeartbeatDetails ()) {
10496 return null ;
10597 }
10698
107- return $ this ->heartbeatDetails ->getValue (0 , $ type );
99+ return $ this ->lastHeartbeatDetails ->getValue (0 , $ type );
108100 }
109101
110102 public function doNotCompleteOnReturn (): void
@@ -117,13 +109,7 @@ public function isDoNotCompleteOnReturn(): bool
117109 return $ this ->doNotCompleteOnReturn ;
118110 }
119111
120- /**
121- * @param mixed $details
122- *
123- * @throws ActivityCompletionException
124- * @throws ActivityCanceledException
125- */
126- public function heartbeat ($ details ): void
112+ public function heartbeat (mixed $ details ): void
127113 {
128114 // we use native host process RPC here to avoid excessive GRPC connections and to handle throttling
129115 // on Golang end
@@ -141,14 +127,29 @@ public function heartbeat($details): void
141127 ],
142128 );
143129
144- if (!empty ($ response ['canceled ' ])) {
145- throw ActivityCanceledException::fromActivityInfo ($ this ->info );
130+ $ cancelled = (bool ) ($ response ['canceled ' ] ?? false );
131+ $ paused = (bool ) ($ response ['paused ' ] ?? false );
132+
133+ if ($ cancelled || $ paused ) {
134+ $ this ->cancellationDetails ??= new ActivityCancellationDetails (
135+ cancelRequested: $ cancelled ,
136+ paused: $ paused ,
137+ );
138+
139+ throw $ cancelled
140+ ? ActivityCanceledException::fromActivityInfo ($ this ->info )
141+ : ActivityPausedException::fromActivityInfo ($ this ->info );
146142 }
147143 } catch (ServiceClientException $ e ) {
148144 throw ActivityCompletionException::fromActivityInfo ($ this ->info , $ e );
149145 }
150146 }
151147
148+ public function getCancellationDetails (): ?ActivityCancellationDetails
149+ {
150+ return $ this ->cancellationDetails ;
151+ }
152+
152153 public function getInstance (): object
153154 {
154155 \assert ($ this ->instance !== null , 'Activity instance is not available ' );
0 commit comments