v2.8.0-BETA2
Pre-releaseHow to develop with Updates
An Update is an operation that can mutate the state of a Workflow Execution and return a response.
Note
RoadRunner 2023.3.12 is required
Note
To enable the Workflow Update feature, you have to set the frontend.enableUpdateWorkflowExecution
Temporal option to true
.
How to define Updates
An Update handler has a name, arguments, response, and an optional validator.
- The name, also called an Update type, is a string.
- The arguments and response must be serializable.
The #[UpdateMethod]
attribute indicates that the method is used to handle and respond to update requests.
#[UpdateMethod]
public function myUpdate(string $signalName);
How to handle Updates in a Workflow
Workflows listen for Update by the update's name.
The handler method can accept multiple serializable input parameters, but it's recommended using only a single parameter.
The function can return a serializable value or void
.
#[WorkflowInterface]
interface FileProcessingWorkflow {
#[WorkflowMethod]
public function processFile(Arguments $args);
#[UpdateMethod]
public function pauseProcessing(): void;
}
Update handlers, unlike Query handlers, can change Workflow state.
The Updates type defaults to the name of the method. To overwrite this default naming and assign a custom Update type, use the #[UpdateMethod]
attribute with the name
parameter.
#[WorkflowInterface]
interface FileProcessingWorkflow {
#[WorkflowMethod]
public function processFile(Arguments $args);
#[UpdateMethod(name: "pause")]
public function pauseProcessing();
}
How to validate an Update in a Workflow
Validate certain aspects of the data sent to the Workflow using an Update Validator method. For instance, a counter Workflow might never want to accept a non-positive number. Use the #[UpdateValidatorMethod]
attribute and set name
to the name of your Update handler. Your Update Validator should accept the same input parameters as your Update Handler and return void
.
#[WorkflowInterface]
interface GreetingWorkflow {
#[WorkflowMethod]
public function getGreetings(): array;
#[UpdateMethod]
public function addGreeting(string $name): int;
#[UpdateValidatorMethod(forUpdate: "addGreeting")]
public function addGreetingValidator(string $name): void;
}
How to send an Update from a Client
To send an Update to a Workflow Execution from a Client, call the Update method, annotated with #[UpdateMethod]
in the Workflow interface, from the Client code.
In the following Client code example, start the Workflow getGreetings
and call the Update method addGreeting
that is handled in the Workflow.
/** @var \Temporal\Client\WorkflowClientInterface $client */
// Create a typed Workflow stub for GreetingsWorkflow
$workflow = $client->newWorkflowStub(GreetingWorkflow::class, $workflowOptions);
// Start the Workflow
$run = $client->start($workflow);
// Send an update to the Workflow. addGreeting returns
// the number of greetings our workflow has received.
$workflow->addGreeting("World");
Async accept
[!NOTE]
To enable an async accept for the Workflow Update feature, you have to set thefrontend.enableUpdateWorkflowExecutionAsyncAccepted
Temporal option totrue
.
In Workflow Update methods, all Workflow features are available, such as executing Activities and child Workflows, and waiting on timers/conditions.
In cases where it's known that the update will take a long time to execute, or you are not interested in the outcome of its execution, you can use the stub method startUpdate
and move on immediately after receiving the validation result.
use Ramsey\Uuid\UuidInterface;
use Temporal\Client\Update\UpdateOptions;
use Temporal\Client\Update\WaitPolicy;
use Temporal\Client\Update\LifecycleStage;
/** @var \Temporal\Client\WorkflowClientInterface $client */
// Create a typed Workflow stub for GreetingsWorkflow
$stub = $client->newUntypedWorkflowStub('GreetingWorkflow', $workflowOptions);
// Start the Workflow
$run = $client->start($stub);
// Send an update to the Workflow. UpdateHandle returns
$handle = $stub->startUpdate('addGreeting', 'World');
// Use the UpdateHandle to get the update result with timeout 2.5 seconds
$result = $handle->getResult(timeout: 2.5);
// You can get more control using UpdateOptions
$resultUuid = $stub->startUpdate(
UpdateOptions::new('storeGreetings')
->withWaitPolicy(WaitPolicy::new()->withLifecycleStage(LifecycleStage::StageCompleted))
->withResultType(UuidInterface::class)
)->getResult();
Full Changelog: v2.7.6...v2.8.0-BETA2