Skip to content

[bundle] No documented way to start a workflow on the DBAL backend; the documented one is Temporal-only #258

Description

@gabiudrescu

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions