Skip to content

Commit d6831f3

Browse files
Unify V2 helper API: remove split functions, add signal(), timer sugar
Remove startActivity(), startChild(), awaitWithTimeout(), awaitSignal(), and parallel() from the V2 public API. The all() function now accepts closures which are resolved via whileInactive(), replacing the start* variants. awaitSignal() is renamed to signal(). awaitWithTimeout() is merged into await() with an optional timeout: parameter. Timer sugar helpers (seconds, minutes, hours, days, weeks, months, years) restored from V1. Closes #278
1 parent 6d1f80a commit d6831f3

42 files changed

Lines changed: 197 additions & 183 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/V2/Support/QueryStateReplayer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ public function replayState(WorkflowRun $run): ReplayState
544544

545545
$this->syncWorkflowCursor($workflow, $sequence);
546546
throw new UnsupportedWorkflowYieldException(sprintf(
547-
'Workflow %s yielded %s. v2 currently supports activity(), await(), awaitWithTimeout(), child(), all(), sideEffect(), getVersion(), timer(), awaitSignal(), and continueAsNew() only.',
547+
'Workflow %s yielded %s. v2 currently supports activity(), child(), async(), all(), await(), signal(), timer(), sideEffect(), continueAsNew(), getVersion(), upsertMemo(), and upsertSearchAttributes() only.',
548548
$run->workflow_class,
549549
get_debug_type($current),
550550
));

src/V2/Support/WorkflowExecutor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,7 @@ public function run(WorkflowRun $run, WorkflowTask $task): ?WorkflowTask
11361136
$run,
11371137
$task,
11381138
new UnsupportedWorkflowYieldException(sprintf(
1139-
'Workflow %s yielded %s. v2 currently supports activity(), await(), awaitWithTimeout(), child(), all(), sideEffect(), getVersion(), timer(), awaitSignal(), and continueAsNew() only.',
1139+
'Workflow %s yielded %s. v2 currently supports activity(), child(), async(), all(), await(), signal(), timer(), sideEffect(), continueAsNew(), getVersion(), upsertMemo(), and upsertSearchAttributes() only.',
11401140
$run->workflow_class,
11411141
get_debug_type($current),
11421142
)),

src/V2/functions.php

Lines changed: 99 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -38,55 +38,6 @@ function activity(string $activity, mixed ...$arguments): mixed
3838
}
3939
}
4040

41-
if (! function_exists(__NAMESPACE__ . '\\startActivity')) {
42-
function startActivity(string $activity, mixed ...$arguments): ActivityCall
43-
{
44-
$options = null;
45-
46-
if (($arguments[0] ?? null) instanceof ActivityOptions) {
47-
$options = array_shift($arguments);
48-
}
49-
50-
return new ActivityCall($activity, $arguments, $options);
51-
}
52-
}
53-
54-
if (! function_exists(__NAMESPACE__ . '\\await')) {
55-
function await(callable $condition, ?string $conditionKey = null): mixed
56-
{
57-
$condition = \Closure::fromCallable($condition);
58-
59-
return WorkflowFiberContext::suspend(new AwaitCall(
60-
$condition,
61-
Support\ConditionWaitKey::normalize($conditionKey),
62-
Support\ConditionWaitDefinition::fingerprint($condition),
63-
));
64-
}
65-
}
66-
67-
if (! function_exists(__NAMESPACE__ . '\\awaitWithTimeout')) {
68-
function awaitWithTimeout(
69-
int|string|CarbonInterval $duration,
70-
callable $condition,
71-
?string $conditionKey = null,
72-
): mixed {
73-
if ($duration instanceof CarbonInterval) {
74-
$duration = (int) ceil($duration->totalSeconds);
75-
} elseif (is_string($duration)) {
76-
$duration = (int) ceil(CarbonInterval::fromString($duration)->totalSeconds);
77-
}
78-
79-
$condition = \Closure::fromCallable($condition);
80-
81-
return WorkflowFiberContext::suspend(new AwaitWithTimeoutCall(
82-
max(0, $duration),
83-
$condition,
84-
Support\ConditionWaitKey::normalize($conditionKey),
85-
Support\ConditionWaitDefinition::fingerprint($condition),
86-
));
87-
}
88-
}
89-
9041
if (! function_exists(__NAMESPACE__ . '\\child')) {
9142
function child(string $workflow, mixed ...$arguments): mixed
9243
{
@@ -100,55 +51,73 @@ function child(string $workflow, mixed ...$arguments): mixed
10051
}
10152
}
10253

103-
if (! function_exists(__NAMESPACE__ . '\\startChild')) {
104-
function startChild(string $workflow, mixed ...$arguments): ChildWorkflowCall
54+
if (! function_exists(__NAMESPACE__ . '\\async')) {
55+
function async(callable $callback): mixed
10556
{
106-
$options = null;
57+
$reflection = match (true) {
58+
is_array($callback) => new ReflectionMethod($callback[0], $callback[1]),
59+
is_string($callback) && str_contains($callback, '::') => new ReflectionMethod($callback),
60+
is_object($callback) && ! $callback instanceof \Closure => new ReflectionMethod($callback, '__invoke'),
61+
default => new ReflectionFunction($callback),
62+
};
10763

108-
if (($arguments[0] ?? null) instanceof ChildWorkflowOptions) {
109-
$options = array_shift($arguments);
64+
if ($reflection->isGenerator()) {
65+
throw StraightLineWorkflowRequiredException::forAsyncCallback();
11066
}
11167

112-
return new ChildWorkflowCall($workflow, $arguments, $options);
68+
return child(AsyncWorkflow::class, new SerializableClosure(\Closure::fromCallable($callback)));
11369
}
11470
}
11571

11672
if (! function_exists(__NAMESPACE__ . '\\all')) {
11773
function all(iterable $calls): mixed
11874
{
119-
return WorkflowFiberContext::suspend(new AllCall($calls));
120-
}
121-
}
75+
$resolved = [];
76+
77+
foreach ($calls as $call) {
78+
if ($call instanceof \Closure) {
79+
$resolved[] = WorkflowFiberContext::whileInactive($call);
80+
} else {
81+
$resolved[] = $call;
82+
}
83+
}
12284

123-
if (! function_exists(__NAMESPACE__ . '\\parallel')) {
124-
function parallel(iterable $calls): AllCall
125-
{
126-
return new AllCall($calls);
85+
return WorkflowFiberContext::suspend(new AllCall($resolved));
12786
}
12887
}
12988

130-
if (! function_exists(__NAMESPACE__ . '\\async')) {
131-
function async(callable $callback): mixed
89+
if (! function_exists(__NAMESPACE__ . '\\await')) {
90+
function await(callable $condition, int|string|CarbonInterval|null $timeout = null, ?string $conditionKey = null): mixed
13291
{
133-
$reflection = match (true) {
134-
is_array($callback) => new ReflectionMethod($callback[0], $callback[1]),
135-
is_string($callback) && str_contains($callback, '::') => new ReflectionMethod($callback),
136-
is_object($callback) && ! $callback instanceof \Closure => new ReflectionMethod($callback, '__invoke'),
137-
default => new ReflectionFunction($callback),
138-
};
92+
$condition = \Closure::fromCallable($condition);
13993

140-
if ($reflection->isGenerator()) {
141-
throw StraightLineWorkflowRequiredException::forAsyncCallback();
94+
if ($timeout !== null) {
95+
if ($timeout instanceof CarbonInterval) {
96+
$timeout = (int) ceil($timeout->totalSeconds);
97+
} elseif (is_string($timeout)) {
98+
$timeout = (int) ceil(CarbonInterval::fromString($timeout)->totalSeconds);
99+
}
100+
101+
return WorkflowFiberContext::suspend(new AwaitWithTimeoutCall(
102+
max(0, $timeout),
103+
$condition,
104+
Support\ConditionWaitKey::normalize($conditionKey),
105+
Support\ConditionWaitDefinition::fingerprint($condition),
106+
));
142107
}
143108

144-
return child(AsyncWorkflow::class, new SerializableClosure(\Closure::fromCallable($callback)));
109+
return WorkflowFiberContext::suspend(new AwaitCall(
110+
$condition,
111+
Support\ConditionWaitKey::normalize($conditionKey),
112+
Support\ConditionWaitDefinition::fingerprint($condition),
113+
));
145114
}
146115
}
147116

148-
if (! function_exists(__NAMESPACE__ . '\\sideEffect')) {
149-
function sideEffect(callable $callback): mixed
117+
if (! function_exists(__NAMESPACE__ . '\\signal')) {
118+
function signal(string $name): mixed
150119
{
151-
return WorkflowFiberContext::suspend(new SideEffectCall(\Closure::fromCallable($callback)));
120+
return WorkflowFiberContext::suspend(new SignalCall($name));
152121
}
153122
}
154123

@@ -165,10 +134,10 @@ function timer(int|string|CarbonInterval $duration): mixed
165134
}
166135
}
167136

168-
if (! function_exists(__NAMESPACE__ . '\\awaitSignal')) {
169-
function awaitSignal(string $name): mixed
137+
if (! function_exists(__NAMESPACE__ . '\\sideEffect')) {
138+
function sideEffect(callable $callback): mixed
170139
{
171-
return WorkflowFiberContext::suspend(new SignalCall($name));
140+
return WorkflowFiberContext::suspend(new SideEffectCall(\Closure::fromCallable($callback)));
172141
}
173142
}
174143

@@ -224,3 +193,54 @@ function getVersion(
224193
return WorkflowFiberContext::suspend(new VersionCall($changeId, $minSupported, $maxSupported));
225194
}
226195
}
196+
197+
// Timer sugar
198+
199+
if (! function_exists(__NAMESPACE__ . '\\seconds')) {
200+
function seconds(int $seconds): mixed
201+
{
202+
return timer($seconds);
203+
}
204+
}
205+
206+
if (! function_exists(__NAMESPACE__ . '\\minutes')) {
207+
function minutes(int $minutes): mixed
208+
{
209+
return timer($minutes * 60);
210+
}
211+
}
212+
213+
if (! function_exists(__NAMESPACE__ . '\\hours')) {
214+
function hours(int $hours): mixed
215+
{
216+
return timer($hours * 3600);
217+
}
218+
}
219+
220+
if (! function_exists(__NAMESPACE__ . '\\days')) {
221+
function days(int $days): mixed
222+
{
223+
return timer($days * 86400);
224+
}
225+
}
226+
227+
if (! function_exists(__NAMESPACE__ . '\\weeks')) {
228+
function weeks(int $weeks): mixed
229+
{
230+
return timer($weeks * 604800);
231+
}
232+
}
233+
234+
if (! function_exists(__NAMESPACE__ . '\\months')) {
235+
function months(int $months): mixed
236+
{
237+
return timer("{$months} months");
238+
}
239+
}
240+
241+
if (! function_exists(__NAMESPACE__ . '\\years')) {
242+
function years(int $years): mixed
243+
{
244+
return timer("{$years} years");
245+
}
246+
}

tests/Fixtures/V2/TestAliasedUpdateWorkflow.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Workflow\UpdateMethod;
99
use Workflow\V2\Attributes\Signal;
1010
use Workflow\V2\Attributes\Type;
11-
use function Workflow\V2\awaitSignal;
11+
use function Workflow\V2\signal;
1212
use Workflow\V2\Workflow;
1313

1414
#[Type('test-aliased-update-workflow')]
@@ -29,7 +29,7 @@ public function handle(): array
2929
$this->stage = 'waiting-for-name';
3030
$this->events[] = 'started';
3131

32-
awaitSignal('name-provided');
32+
signal('name-provided');
3333

3434
$this->stage = 'completed';
3535
$this->events[] = 'signal:received';

tests/Fixtures/V2/TestAwaitWithTimeoutWorkflow.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Workflow\QueryMethod;
88
use Workflow\UpdateMethod;
99
use Workflow\V2\Attributes\Type;
10-
use function Workflow\V2\awaitWithTimeout;
10+
use function Workflow\V2\await;
1111
use Workflow\V2\Workflow;
1212

1313
#[Type('test-await-timeout-workflow')]
@@ -23,7 +23,7 @@ public function handle(): array
2323
{
2424
$this->stage = 'waiting-for-approval';
2525

26-
$approved = awaitWithTimeout(5, fn (): bool => $this->approved);
26+
$approved = await(fn (): bool => $this->approved, timeout: 5);
2727

2828
if (! $approved) {
2929
$this->timedOut = true;

tests/Fixtures/V2/TestBroadChildFailureCatchWorkflow.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use RuntimeException;
88
use Workflow\QueryMethod;
99
use Workflow\V2\Attributes\Signal;
10-
use function Workflow\V2\awaitSignal;
10+
use function Workflow\V2\signal;
1111
use function Workflow\V2\child;
1212
use Workflow\V2\Workflow;
1313

@@ -36,7 +36,7 @@ public function handle(string $orderId): array
3636
];
3737
}
3838

39-
$resume = awaitSignal('resume');
39+
$resume = signal('resume');
4040
$this->stage = 'completed';
4141

4242
return [

tests/Fixtures/V2/TestBroadFailureCatchWorkflow.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Workflow\QueryMethod;
99
use function Workflow\V2\activity;
1010
use Workflow\V2\Attributes\Signal;
11-
use function Workflow\V2\awaitSignal;
11+
use function Workflow\V2\signal;
1212
use Workflow\V2\Workflow;
1313

1414
#[Signal('resume')]
@@ -36,7 +36,7 @@ public function handle(string $orderId): array
3636
];
3737
}
3838

39-
$resume = awaitSignal('resume');
39+
$resume = signal('resume');
4040
$this->stage = 'completed';
4141

4242
return [

tests/Fixtures/V2/TestChildHandleChildWorkflow.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Workflow\QueryMethod;
88
use Workflow\V2\Attributes\Signal;
99
use Workflow\V2\Attributes\Type;
10-
use function Workflow\V2\awaitSignal;
10+
use function Workflow\V2\signal;
1111
use Workflow\V2\Workflow;
1212

1313
#[Type('test-child-handle-child-workflow')]
@@ -20,7 +20,7 @@ public function handle(): array
2020
{
2121
$this->stage = 'waiting-for-approval';
2222

23-
$approvedBy = awaitSignal('approved-by');
23+
$approvedBy = signal('approved-by');
2424

2525
$this->stage = 'approved';
2626

tests/Fixtures/V2/TestCommandTargetWorkflow.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Workflow\UpdateMethod;
99
use Workflow\V2\Attributes\Signal;
1010
use Workflow\V2\Attributes\Type;
11-
use function Workflow\V2\awaitSignal;
11+
use function Workflow\V2\signal;
1212
use Workflow\V2\Workflow;
1313

1414
#[Type('test-command-target-workflow')]
@@ -23,7 +23,7 @@ final class TestCommandTargetWorkflow extends Workflow
2323
{
2424
public function handle(): array
2525
{
26-
awaitSignal('approved-by');
26+
signal('approved-by');
2727

2828
return [
2929
'workflow_id' => $this->workflowId(),

tests/Fixtures/V2/TestConfiguredContinueSignalWorkflow.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Workflow\QueryMethod;
88
use Workflow\UpdateMethod;
99
use Workflow\V2\Attributes\Signal;
10-
use function Workflow\V2\awaitSignal;
10+
use function Workflow\V2\signal;
1111
use function Workflow\V2\continueAsNew;
1212
use Workflow\V2\Workflow;
1313

@@ -29,7 +29,7 @@ public function handle(int $count = 0): mixed
2929
return continueAsNew($count + 1);
3030
}
3131

32-
$name = awaitSignal('name-provided');
32+
$name = signal('name-provided');
3333

3434
return [
3535
'name' => $name,

0 commit comments

Comments
 (0)