|
10 | 10 | use Temporal\Client\Update\UpdateOptions; |
11 | 11 | use Temporal\Client\WorkflowClientInterface; |
12 | 12 | use Temporal\Client\WorkflowOptions; |
| 13 | +use Temporal\Common\WorkflowIdConflictPolicy; |
13 | 14 | use Temporal\Exception\Client\WorkflowExecutionAlreadyStartedException; |
14 | 15 | use Temporal\Exception\Client\WorkflowFailedException; |
15 | 16 | use Temporal\Exception\Client\WorkflowServiceException; |
@@ -138,6 +139,96 @@ public function failOnReuseExistingWorkflowId( |
138 | 139 | $stub1->signal('exit'); |
139 | 140 | } |
140 | 141 | } |
| 142 | + |
| 143 | + #[Test] |
| 144 | + public function useExistingReturnsRunningExecution( |
| 145 | + WorkflowClientInterface $client, |
| 146 | + Feature $feature, |
| 147 | + ): void { |
| 148 | + $id = Uuid::uuid7()->__toString(); |
| 149 | + |
| 150 | + $first = $client->newUntypedWorkflowStub( |
| 151 | + 'Extra_Update_UseExisting', |
| 152 | + WorkflowOptions::new()->withTaskQueue($feature->taskQueue)->withWorkflowId($id), |
| 153 | + ); |
| 154 | + $client->start($first); |
| 155 | + $firstRunId = $first->getExecution()->getRunID(); |
| 156 | + |
| 157 | + $second = $client->newUntypedWorkflowStub( |
| 158 | + 'Extra_Update_UseExisting', |
| 159 | + WorkflowOptions::new() |
| 160 | + ->withTaskQueue($feature->taskQueue) |
| 161 | + ->withWorkflowId($id) |
| 162 | + ->withWorkflowIdConflictPolicy(WorkflowIdConflictPolicy::UseExisting), |
| 163 | + ); |
| 164 | + |
| 165 | + try { |
| 166 | + $client->start($second); |
| 167 | + |
| 168 | + $this->assertSame($id, $second->getExecution()->getID()); |
| 169 | + $this->assertSame( |
| 170 | + $firstRunId, |
| 171 | + $second->getExecution()->getRunID(), |
| 172 | + 'UseExisting must resolve to the already-running execution instead of throwing', |
| 173 | + ); |
| 174 | + } finally { |
| 175 | + $first->signal('exit'); |
| 176 | + } |
| 177 | + } |
| 178 | + |
| 179 | + #[Test] |
| 180 | + public function failPolicyThrowsOnRunningWorkflowId( |
| 181 | + WorkflowClientInterface $client, |
| 182 | + Feature $feature, |
| 183 | + ): void { |
| 184 | + $id = Uuid::uuid7()->__toString(); |
| 185 | + |
| 186 | + $first = $client->newUntypedWorkflowStub( |
| 187 | + 'Extra_Update_UseExisting', |
| 188 | + WorkflowOptions::new()->withTaskQueue($feature->taskQueue)->withWorkflowId($id), |
| 189 | + ); |
| 190 | + $client->start($first); |
| 191 | + |
| 192 | + $second = $client->newUntypedWorkflowStub( |
| 193 | + 'Extra_Update_UseExisting', |
| 194 | + WorkflowOptions::new() |
| 195 | + ->withTaskQueue($feature->taskQueue) |
| 196 | + ->withWorkflowId($id) |
| 197 | + ->withWorkflowIdConflictPolicy(WorkflowIdConflictPolicy::Fail), |
| 198 | + ); |
| 199 | + |
| 200 | + try { |
| 201 | + $this->expectException(WorkflowExecutionAlreadyStartedException::class); |
| 202 | + $client->start($second); |
| 203 | + } finally { |
| 204 | + $first->signal('exit'); |
| 205 | + } |
| 206 | + } |
| 207 | + |
| 208 | + #[Test] |
| 209 | + public function useExistingStartsFreshWhenNoneRunning( |
| 210 | + WorkflowClientInterface $client, |
| 211 | + Feature $feature, |
| 212 | + ): void { |
| 213 | + $id = Uuid::uuid7()->__toString(); |
| 214 | + |
| 215 | + $stub = $client->newUntypedWorkflowStub( |
| 216 | + 'Extra_Update_UseExisting', |
| 217 | + WorkflowOptions::new() |
| 218 | + ->withTaskQueue($feature->taskQueue) |
| 219 | + ->withWorkflowId($id) |
| 220 | + ->withWorkflowIdConflictPolicy(WorkflowIdConflictPolicy::UseExisting), |
| 221 | + ); |
| 222 | + |
| 223 | + try { |
| 224 | + $client->start($stub); |
| 225 | + |
| 226 | + $this->assertSame($id, $stub->getExecution()->getID()); |
| 227 | + $this->assertNotSame('', $stub->getExecution()->getRunID()); |
| 228 | + } finally { |
| 229 | + $stub->signal('exit'); |
| 230 | + } |
| 231 | + } |
141 | 232 | } |
142 | 233 |
|
143 | 234 | #[WorkflowInterface] |
@@ -195,3 +286,22 @@ public function __construct( |
195 | 286 | public int $length = 0, |
196 | 287 | ) {} |
197 | 288 | } |
| 289 | + |
| 290 | +#[WorkflowInterface] |
| 291 | +class UseExistingWorkflow |
| 292 | +{ |
| 293 | + private bool $exit = false; |
| 294 | + |
| 295 | + #[WorkflowMethod(name: 'Extra_Update_UseExisting')] |
| 296 | + public function handle(): \Generator |
| 297 | + { |
| 298 | + yield Workflow::await(fn(): bool => $this->exit); |
| 299 | + return 'done'; |
| 300 | + } |
| 301 | + |
| 302 | + #[Workflow\SignalMethod] |
| 303 | + public function exit(): void |
| 304 | + { |
| 305 | + $this->exit = true; |
| 306 | + } |
| 307 | +} |
0 commit comments