What a newcomer hits
The docs show one way to start an execution:
$factory->workflowClient()->startAsync(
CheckoutWorkflow::class,
['orderId' => $order->getIncrementId()],
'order-' . $order->getIncrementId(),
);
There is no workflowClient() on the DBAL backend. grep -rn 'workflowClient' vendor/gplanchat/ returns one hit, in a comment in DurableExtension.php describing the Temporal dispatcher.
The call that actually works is not mentioned anywhere:
$this->resumeDispatcher->dispatchNewWorkflowRun(
'order-' . $orderNumber, // business execution id
(new WorkflowDefinitionLoader())->workflowTypeForClass(OrderFulfilmentWorkflow::class),
['orderNumber' => $orderNumber, 'totalInCents' => $total],
);
I found it by reading the docblock on ResumeWorkflowMessage, which points at WorkflowResumeDispatcher::dispatchNewWorkflowRun. Two things are surprising there:
- The port is named for resuming. Nothing about
WorkflowResumeDispatcher suggests it is also how an execution is born. Its own docblock for the method says "after continue-as-new or equivalent" - starting a workflow from a controller is not obviously "equivalent".
- The workflow type is a string. Passing the FQCN works because the registry indexes both, but the journal and the dashboard then show the FQCN. Getting the alias means instantiating
WorkflowDefinitionLoader yourself. A newcomer will pass ::class and wonder why the admin shows App\Workflow\OrderFulfilmentWorkflow instead of OrderFulfilment.
Sending the signal has the same shape - you construct the transport message by hand:
$this->bus->dispatch(new DeliverWorkflowSignalMessage(
'order-' . $orderNumber,
WarehouseSignal::Decided,
['accepted' => true, 'trackingNumber' => 'TRK-1'],
));
Ask
One WorkflowClient service, autowirable, with the same surface on both backends:
public function startAsync(string $workflowClass, array $input, string $executionId): void;
public function signal(string $executionId, \BackedEnum|string $name, array $payload = []): void;
It resolves the alias itself, so the journal is named the same way whoever calls it. If the API is meant to stay as it is, the reference should show the DBAL call next to the Temporal one - the current text reads as if there were only one way.
What a newcomer hits
The docs show one way to start an execution:
There is no
workflowClient()on the DBAL backend.grep -rn 'workflowClient' vendor/gplanchat/returns one hit, in a comment inDurableExtension.phpdescribing the Temporal dispatcher.The call that actually works is not mentioned anywhere:
I found it by reading the docblock on
ResumeWorkflowMessage, which points atWorkflowResumeDispatcher::dispatchNewWorkflowRun. Two things are surprising there:WorkflowResumeDispatchersuggests it is also how an execution is born. Its own docblock for the method says "after continue-as-new or equivalent" - starting a workflow from a controller is not obviously "equivalent".WorkflowDefinitionLoaderyourself. A newcomer will pass::classand wonder why the admin showsApp\Workflow\OrderFulfilmentWorkflowinstead ofOrderFulfilment.Sending the signal has the same shape - you construct the transport message by hand:
Ask
One
WorkflowClientservice, autowirable, with the same surface on both backends:It resolves the alias itself, so the journal is named the same way whoever calls it. If the API is meant to stay as it is, the reference should show the DBAL call next to the Temporal one - the current text reads as if there were only one way.