Skip to content
durable-workflowPublic

About

PHP client and worker SDK for Durable Workflow Cloud and self-hosted Server.

Topics

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Latest commit

 

History

581 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Durable Workflow PHP SDK

CI status Quality Gate Packagist version Supported PHP versions MIT license

The first-party PHP client and worker SDK for Durable Workflow Cloud and self-hosted Durable Workflow Server. Use it from plain PHP, Laravel, or Symfony to run durable workflows outside the application process while keeping framework-native configuration, dependency injection, commands, logging, and tests.

Install

composer require durable-workflow/sdk

The SDK requires PHP 8.1 or newer. It uses the official apache/avro package for portable payloads and accepts any PSR-18 HTTP client.

Upgrading from PHP SDK 2 requires a workflow registration migration. Register workflow classes or a WorkflowFactory that constructs a fresh handler instead of passing prebuilt workflow objects. Workflow container bindings must be transient, while injected collaborators may remain shared. Constructors run during replay and must be free of external side effects. See the registration migration guide.

Choose Your Path

Starting point Recommended guide
Plain PHP client or worker First workflow
Laravel v1 or v2 embedded Choose a Laravel ownership model
Laravel service mode Laravel service-mode bridge
Laravel HTTP hosting FPM and optional Octane example
Symfony service mode Symfony bundle
Runtime authentication Authentication guide

Laravel applications can keep Durable Workflow embedded or move execution to Cloud or Server. The service-mode bridge supplies container bindings, config, an Artisan worker command, diagnostics, a facade, and a test fake. Symfony gets the same application-shaped experience through its bundle and Console worker.

Author a Workflow

Handlers can be ordinary attributed classes resolved by the worker container:

<?php

use DurableWorkflow\Attribute\Activity;
use DurableWorkflow\Attribute\Workflow;
use DurableWorkflow\Worker\ActivityContext;
use DurableWorkflow\Worker\WorkflowContext;

final class GreetingWorkflow
{
    #[Workflow('example.greeting')]
    public function run(WorkflowContext $context, string $name): array
    {
        $greeting = $context->activity('example.greet', [$name]);

        return ['greeting' => $greeting];
    }
}

final class GreetingActivities
{
    #[Activity('example.greet')]
    public function greet(ActivityContext $context, string $name): string
    {
        return "Hello, {$name}";
    }
}

Register the classes on a task queue and start polling:

use DurableWorkflow\Client;
use DurableWorkflow\Worker;

$client = new Client(
    getenv('DURABLE_WORKFLOW_RUNTIME_URL'),
    namespace: getenv('DURABLE_WORKFLOW_NAMESPACE'),
    workerToken: getenv('DURABLE_WORKFLOW_WORKER_TOKEN'),
);

Worker::create($client, 'greetings')
    ->register(GreetingWorkflow::class, GreetingActivities::class)
    ->run();

Start the workflow from a client process using a client-role credential:

$client = new Client(
    getenv('DURABLE_WORKFLOW_RUNTIME_URL'),
    namespace: getenv('DURABLE_WORKFLOW_NAMESPACE'),
    controlToken: getenv('DURABLE_WORKFLOW_CLIENT_TOKEN'),
);

$handle = $client->startWorkflow(
    workflowType: 'example.greeting',
    workflowId: 'greeting-'.bin2hex(random_bytes(12)),
    taskQueue: 'greetings',
    input: ['PHP'],
);

var_dump($handle->result());

For Cloud, use the complete namespace runtime URL exactly as provisioned. For self-hosted Server, use its origin such as http://localhost:8080. Keep client and worker credentials in separate processes.

The complete plain PHP quickstart includes the three runnable files, environment setup, expected output, and common failure diagnostics.

Capabilities

  • Workflows, activities, child workflows, timers, retries, and heartbeats
  • Signals, queries, updates, condition waits, and message streams
  • Parallel work, sagas, cancellation, continue-as-new, and version markers
  • Schedules, search attributes, memo, external payloads, and worker versioning
  • Replay testing, in-memory client fakes, Laravel and Symfony test helpers
  • Stable workflow handles and machine-readable runtime diagnostics

Configure optional execution tracing and log correlation with your application-owned OpenTelemetry provider. Durable caller propagation requires the connected Server to advertise the supported capability.

See the complete SDK reference for control-plane APIs, worker configuration, Message Streams, framework setup, and testing examples. The generated API reference documents every public class and method.

Activity runtime leases

When the runtime advertises activity_lease_renewal, the managed Worker keeps an activity's runtime lease and Worker presence alive independently of a blocking callback. Ordinary callbacks keep running inline with their original injected services and captured memory. This requires PHP CLI with proc_open enabled.

Runtime maintenance does not record application progress or extend an activity, heartbeat, workflow or worker-session TTL deadline. Continue calling ActivityContext::heartbeat() when an activity has a heartbeat timeout. After authority is lost, the Worker discards late outcomes. It cannot undo external side effects or forcibly stop ordinary inline application code.

The default HTTP transport and static worker credentials work automatically. Custom HTTP clients or dynamic authentication require withActivityLeaseBootstrap() so the independent process recreates their actual TLS and authentication settings.

Cooperative cancellation release candidate

Cooperative requests let workflow code perform bounded, replayable cleanup. Use a Server that advertises protocol 1.20 and the required capabilities, set the Client's workerProtocolVersion to '1.20', and construct the Worker with enableCooperativeCancellation: true. Enable enablePreparedLocalActivities for durable local callback admission, stop receipts and explicit local policies. Independently cancellable scopes remain disabled.

This opt-in requires Unix CLI with pcntl and posix. Activity callbacks run in supervised child processes so cancellation can stop blocking code without application heartbeats. Open handler-owned connections in the callback process and return results explicitly. Changes to captured process memory do not update the owning worker.

Use requestCancellation() for cooperative cleanup. Existing cancel() closes the run immediately. See the cancellation guide for operation policies, immutable context, shielding and recovery.

Development

composer install
composer test
composer analyse
composer benchmark-avro-value

See CONTRIBUTING.md for contribution and validation details.

License

MIT

About

PHP client and worker SDK for Durable Workflow Cloud and self-hosted Server.

Topics

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages