v2.8.0
What's Changed
- Expose Workflow Updates by @roxblnfk in #398
Sample - Add Carbon v3 and remove unnecessary packages by @devvitalii in #404
Now SDK is compatible with Symfony 7 - A few life quality improvements by @roxblnfk in #405
- Make exception messages shorter and more elegant: hide internal stack trace and deduplicate the error reason
- Throw an exception with clear message if Client is used without gRPC extension; add
ext-grpc
into suggested packages
Warning
RoadRunner >=2023.3.12 is required
How to develop with Updates
An Update is an operation that can mutate the state of a Workflow Execution and return a response.
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 the async Workflow Update feature, you have to set the frontend.enableUpdateWorkflowExecutionAsyncAccepted
Temporal option to true
.
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.
/** @var \Temporal\Client\WorkflowClientInterface $client */
use Ramsey\Uuid\UuidInterface;
use Temporal\Client\Update\UpdateOptions;
use Temporal\Client\Update\WaitPolicy;
use Temporal\Client\Update\LifecycleStage;
// 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();
New Contributors
- @devvitalii made their first contribution in #404
Full Changelog: v2.7.6...v2.8.0