### Start Example Workflow in Laravel Sample App Source: https://laravel-workflow.com/sample-app This command initiates an example workflow defined within the Laravel Workflow sample application. It demonstrates how to trigger a workflow from the command line, allowing you to observe its execution. ```bash php artisan app:workflow ``` -------------------------------- ### Initialize Laravel Workflow Sample Application Source: https://laravel-workflow.com/sample-app This command runs a custom Artisan command to initialize the Laravel application. It typically sets up the database, installs additional dependencies, and performs other initial setup tasks required for the sample app's functionality. ```bash php artisan app:init ``` -------------------------------- ### Example Webhook Routes After Custom Path Configuration Source: https://laravel-workflow.com/features/webhooks Provides examples of the new webhook URLs for starting and signaling workflows after the `webhooks_route` configuration has been changed to 'workflows'. ```text POST /workflows/start/order-workflow POST /workflows/signal/order-workflow/{workflowId}/mark-as-shipped ``` -------------------------------- ### Start a new Laravel Workflow instance Source: https://laravel-workflow.com/defining-workflows/starting-workflows Demonstrates how to create a new workflow instance using `WorkflowStub::make()` and then start its execution asynchronously by calling the `start()` method. Any data passed to `start()` will be sent to the workflow's `execute()` method. ```PHP use Workflow\WorkflowStub; $workflow = WorkflowStub::make(MyWorkflow::class); $workflow->start(); ``` -------------------------------- ### Example Usage of Webhook URL Helper in Activity Source: https://laravel-workflow.com/features/webhooks This PHP example demonstrates how to use the `$this->webhookUrl()` helper within an `Activity` class. It shows how to generate both the workflow start URL and a signal URL, along with comments indicating the expected output paths. ```php use Workflow\Activity; class ShipOrderActivity extends Activity { public function execute(string $email): void { $startUrl = $this->webhookUrl(); // $startUrl = '/webhooks/start/order-workflow'; $signalUrl = $this->webhookUrl('markAsShipped'); // $signalUrl = '/webhooks/signal/order-workflow/{workflowId}/mark-as-shipped'; } } ``` -------------------------------- ### Example cURL Request to Start a Workflow Source: https://laravel-workflow.com/features/webhooks This cURL command illustrates how to send a POST request to the webhook endpoint to start the `order-workflow`, including setting the content type and providing a JSON payload with the `orderId`. ```curl curl -X POST "https://example.com/webhooks/start/order-workflow" \ -H "Content-Type: application/json" \ -d '{"orderId": 123}' ``` -------------------------------- ### Install Composer Dependencies for Laravel Sample App Source: https://laravel-workflow.com/sample-app This command installs all the necessary PHP dependencies for the Laravel Workflow sample application using Composer. It's a crucial first step to set up the project environment after cloning or creating a codespace. ```bash composer install ``` -------------------------------- ### Publish Laravel Workflow Database Migrations Source: https://laravel-workflow.com/installation After installing the package, publish the database migration files to your project. These migrations are essential for creating the tables Laravel Workflow needs. ```Bash php artisan vendor:publish --provider="Workflow\Providers\WorkflowServiceProvider" --tag="migrations" ``` -------------------------------- ### Defining a Workflow Class for Webhook Start Source: https://laravel-workflow.com/features/webhooks To allow an external system to initiate a workflow via a webhook, the `#[Webhook]` attribute must be applied to the workflow class. This example shows an `OrderWorkflow` class configured to be started by a webhook. ```php use Workflow\Webhook; use Workflow\Workflow; #[Webhook] class OrderWorkflow extends Workflow { public function execute($orderId) { // your code here } } ``` -------------------------------- ### Start a Laravel Workflow and Pass Data Source: https://laravel-workflow.com/defining-workflows/passing-data Demonstrates how to initiate a workflow and pass a simple string argument using the `start()` method of `WorkflowStub`. It also shows how to wait for the workflow to complete and retrieve its output. ```PHP use Workflow\WorkflowStub; $workflow = WorkflowStub::make(MyWorkflow::class); $workflow->start('world'); while ($workflow->running()); $workflow->output(); => 'Hello, world!' ``` -------------------------------- ### Run Laravel Workflow Database Migrations Source: https://laravel-workflow.com/installation Execute the published migrations to create the required database tables for Laravel Workflow. This step prepares your database for workflow and activity storage. ```Bash php artisan migrate ``` -------------------------------- ### Install Laravel Workflow Composer Package Source: https://laravel-workflow.com/installation Use Composer to add the Laravel Workflow package to your Laravel project. This command downloads and installs the necessary files. ```Bash composer require laravel-workflow/laravel-workflow ``` -------------------------------- ### Start Laravel Queue Worker for Workflow Processing Source: https://laravel-workflow.com/sample-app This command starts the Laravel queue worker, which is essential for processing workflows and activities in the background. It listens for and processes jobs dispatched to the queue, enabling asynchronous operations. ```bash php artisan queue:work ``` -------------------------------- ### Load an existing Laravel Workflow by ID Source: https://laravel-workflow.com/defining-workflows/starting-workflows Shows how to retrieve an instance of an already existing workflow using its unique workflow ID. This allows for further interaction with a running or completed workflow. ```PHP use Workflow\WorkflowStub; $workflow = WorkflowStub::load($id); ``` -------------------------------- ### Webhook Endpoint for Starting a Workflow Source: https://laravel-workflow.com/features/webhooks This API endpoint specifies the HTTP method and URL path for starting an `order-workflow` instance via a webhook. The workflow name in the URL is derived from the class name. ```APIDOC POST /webhooks/start/order-workflow ``` -------------------------------- ### Example cURL Request to Send a Signal Source: https://laravel-workflow.com/features/webhooks This cURL command demonstrates how to send a POST request to the webhook endpoint to trigger the `mark-as-shipped` signal on a specific `order-workflow` instance. ```curl curl -X POST "https://example.com/webhooks/signal/order-workflow/1/mark-as-shipped" \ -H "Content-Type: application/json" ``` -------------------------------- ### Parameters for Webhook URL Helper Method Source: https://laravel-workflow.com/features/webhooks This documentation describes the optional `$signalMethod` parameter for the `webhookUrl()` helper. It clarifies that an empty parameter returns the URL for starting the workflow, while a provided string returns the URL for sending a signal to an active workflow instance. ```APIDOC string $signalMethod = '' (optional) If empty, returns the URL for starting the workflow. If provided, returns the URL for sending a signal to an active workflow instance. ``` -------------------------------- ### Define Workflow Class with Shared Queue Connection (Workflow Microservice) Source: https://laravel-workflow.com/configuration/microservices This example shows a `MyWorkflow` class in the workflow microservice, configured to use the 'shared' queue connection and a unique 'workflow' queue name. It demonstrates how a workflow initiates an activity in another microservice. ```php use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public $connection = 'shared'; public $queue = 'workflow'; public function execute($name) { $result = yield ActivityStub::make(MyActivity::class, $name); return $result; } } ``` -------------------------------- ### Generate a new Laravel Workflow using Artisan Source: https://laravel-workflow.com/defining-workflows/workflows This command-line snippet demonstrates how to use the `make:workflow` Artisan command to quickly generate a new workflow class file in a Laravel project, providing a starting point for defining workflow logic. ```bash php artisan make:workflow MyWorkflow ``` -------------------------------- ### Define Activity Class with Shared Queue Connection (Activity Microservice) Source: https://laravel-workflow.com/configuration/microservices This example shows a `MyActivity` class in the activity microservice, configured to use the 'shared' queue connection and a unique 'activity' queue name. It demonstrates the implementation of an activity that can be called by a workflow. ```php use Workflow\Activity; class MyActivity extends Activity { public $connection = 'shared'; public $queue = 'activity'; public function execute($name) { return "Hello, {$name}!"; } } ``` -------------------------------- ### Basic Usage of Webhook URL Helper Source: https://laravel-workflow.com/features/webhooks The `$this->webhookUrl()` helper method, available within workflows and activities, generates the appropriate webhook URL. Calling it without arguments provides the URL to start the workflow, while providing a method name generates the URL for sending a signal. ```php $this->webhookUrl(); $this->webhookUrl('signalMethod'); ``` -------------------------------- ### APIDOC: WorkflowStarted Event in Laravel Workflow Source: https://laravel-workflow.com/features/events Documents the WorkflowStarted event, which is triggered when a workflow begins its execution, providing details about the workflow's identity, class, arguments, and start time. ```APIDOC WorkflowStarted: Attributes: workflowId: Unique identifier for the workflow. class: Class name of the workflow. arguments: Arguments passed to the workflow. timestamp: Timestamp of when the workflow started. ``` -------------------------------- ### APIDOC: ActivityStarted Event in Laravel Workflow Source: https://laravel-workflow.com/features/events Documents the ActivityStarted event, triggered when an activity within a workflow begins, detailing its parent workflow ID, activity ID, class, index, arguments, and start time. ```APIDOC ActivityStarted: Attributes: workflowId: The ID of the parent workflow. activityId: Unique identifier for the activity. class: Class name of the activity. index: The position of the activity within the workflow. arguments: Arguments passed to the activity. timestamp: Timestamp of when the activity started. ``` -------------------------------- ### Getting accurate workflow time with WorkflowStub::sideEffect and WorkflowStub::now() Source: https://laravel-workflow.com/features/timers This snippet shows the correct way to get the current time within a workflow using `WorkflowStub::sideEffect` and `WorkflowStub::now()`. This approach ensures time calculations are accurate and consistent with the workflow system's event log, preventing replay inconsistencies. ```PHP $start = yield WorkflowStub::sideEffect(fn () => WorkflowStub::now()); ``` -------------------------------- ### Execute Laravel Workflow Activities in Series Source: https://laravel-workflow.com/features/concurrency This example demonstrates how to execute multiple activities sequentially in a Laravel Workflow. Each activity is yielded individually, causing the workflow to pause and wait for its completion before proceeding to the next one. ```php use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute() { return [ yield ActivityStub::make(MyActivity1::class), yield ActivityStub::make(MyActivity1::class), yield ActivityStub::make(MyActivity1::class), ]; } } ``` -------------------------------- ### Executing Async Activities in Laravel Workflows Source: https://laravel-workflow.com/features/child-workflows This example shows how to use `ActivityStub::async()` to execute a callback in the context of a separate workflow. This allows for asynchronous execution of multiple activities, returning their results as an array, without necessarily creating a full child workflow. ```PHP use Workflow\ActivityStub; use Workflow\Workflow; class AsyncWorkflow extends Workflow { public function execute() { [$result, $otherResult] = yield ActivityStub::async(function () { $result = yield ActivityStub::make(Activity::class); $otherResult = yield ActivityStub::make(OtherActivity::class, 'other'); return [$result, $otherResult]; }); } } ``` -------------------------------- ### Schedule Workflow Pruning Command Source: https://laravel-workflow.com/configuration/pruning-workflows You can automate the pruning process by scheduling the `model:prune` Artisan command. This example demonstrates scheduling the command to run daily within your application's `routes/console.php` file. ```php Schedule::command('model:prune', [ '--model' => StoredWorkflow::class, ])->daily(); ``` -------------------------------- ### Defining a Signal Method for Webhook Access Source: https://laravel-workflow.com/features/webhooks To enable external systems to send signals to an active workflow instance, both `#[SignalMethod]` and `#[Webhook]` attributes must be applied to the target method within the workflow class. This example defines a `markAsShipped` signal method for `OrderWorkflow`. ```php use Workflow\SignalMethod; use Workflow\Webhook; use Workflow\Workflow; class OrderWorkflow extends Workflow { protected bool $shipped = false; #[SignalMethod] #[Webhook] public function markAsShipped() { $this->shipped = true; } } ``` -------------------------------- ### Assert Dispatched Activities with Callback Truth Test Source: https://laravel-workflow.com/testing This PHP example illustrates how to use a closure with `assertDispatched` or `assertNotDispatched` to perform a 'truth test' on the arguments passed to a dispatched activity or child workflow, allowing for more specific assertions. ```PHP WorkflowStub::assertDispatched(TestOtherActivity::class, function ($string) { return $string === 'other'; }); ``` -------------------------------- ### Define a Laravel Workflow with Sequential and Parallel Activities in PHP Source: https://laravel-workflow.com/how-it-works This PHP code snippet demonstrates how to define a workflow class in Laravel Workflow. It extends the `Workflow` base class and uses the `execute()` generator method to orchestrate activities. The example shows how to yield individual activities sequentially using `ActivityStub::make()` and how to run multiple activities in parallel using `ActivityStub::all()`. ```PHP use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute() { return [ yield ActivityStub::make(TestActivity::class), yield ActivityStub::make(TestOtherActivity::class), yield ActivityStub::all([ ActivityStub::make(TestParallelActivity::class), ActivityStub::make(TestParallelOtherActivity::class), ]), ]; } } ``` -------------------------------- ### Execute Laravel Workflow Activities in Parallel Source: https://laravel-workflow.com/features/concurrency This example shows how to execute multiple activities concurrently in a Laravel Workflow. By wrapping activity stubs in `ActivityStub::all()` and yielding the result, the workflow waits for all activities to complete as a group. ```php use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute() { return yield ActivityStub::all([ ActivityStub::make(MyActivity1::class), ActivityStub::make(MyActivity2::class), ActivityStub::make(MyActivity3::class), ]); } } ``` -------------------------------- ### Run Laravel Queue Worker for a Dedicated Queue Source: https://laravel-workflow.com/configuration/ensuring-same-server This command initiates a Laravel queue worker that is configured to process jobs exclusively from the specified queue. This setup is crucial for ensuring that workflow activities assigned to this queue execute on the same server, enabling them to share local file system data. ```Bash php artisan queue:work --queue=my_dedicated_queue ``` -------------------------------- ### Using WorkflowStub::timer for delays in Laravel Workflow Source: https://laravel-workflow.com/features/timers This example demonstrates how to use `WorkflowStub::timer($seconds)` within a Laravel Workflow to pause execution for a specified duration. The method returns a `Promise` that resolves after the timer finishes, allowing the workflow to resume. ```PHP use Workflow\WorkflowStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute() { // Wait for 5 seconds before continuing yield WorkflowStub::timer(5); // Do something after the timer has finished return 'Hello world'; } } ``` -------------------------------- ### Catch Activity Exceptions in a Laravel Workflow Source: https://laravel-workflow.com/failures-and-recovery This PHP example illustrates how a Laravel Workflow can catch and handle exceptions thrown by an activity. It uses a "try-catch" block around the "ActivityStub::make" call to gracefully manage activity failures within the workflow's execution logic. ```PHP use Exception; use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute() { try { $result = yield ActivityStub::make(MyActivity::class); } catch (Exception) { // handle the exception here } } } ``` -------------------------------- ### Trigger a Signal on a Laravel Workflow Instance Source: https://laravel-workflow.com/features/signals This PHP snippet shows how to trigger a signal on an existing Laravel Workflow instance. It uses `WorkflowStub::make()` to get a workflow instance and then calls the `setReady` method, passing `true` as an argument, effectively signaling the workflow. ```php use Workflow\WorkflowStub; $workflow = WorkflowStub::make(MyWorkflow::class); $workflow->setReady(true); ``` -------------------------------- ### Pause Workflow Execution Until a Condition is Met with await() Source: https://laravel-workflow.com/features/signals This PHP code illustrates how to use `WorkflowStub::await()` within a Laravel Workflow to pause its execution until a specified condition is met. In this example, the workflow will pause until the `$ready` property becomes true, typically set by an incoming signal. ```php use Workflow\Workflow; use Workflow\WorkflowStub; class MyWorkflow extends Workflow { private bool $ready = false; public function execute() { yield WorkflowStub::await(fn () => $this->ready); } } ``` -------------------------------- ### Obtain Workflow ID when Starting a Workflow Source: https://laravel-workflow.com/defining-workflows/workflow-id This snippet demonstrates how to retrieve the unique identifier of a workflow immediately after it is initiated using `WorkflowStub::make()` and accessing the `id()` method. This ID is essential for tracking the workflow's progress and enabling subsequent interactions like signaling or querying its state. ```php use Workflow\WorkflowStub; $workflow = WorkflowStub::make(MyWorkflow::class); $workflowId = $workflow->id(); ``` -------------------------------- ### Extend Laravel Workflow Models for Custom Database Connection Source: https://laravel-workflow.com/configuration/database-connection This section provides code examples for extending various base Laravel Workflow model classes (StoredWorkflow, StoredWorkflowException, StoredWorkflowLog, StoredWorkflowSignal, StoredWorkflowTimer) to specify a custom database connection. This is necessary when you want to use a database connection different from your application's default, ensuring workflow data is stored in the desired database. ```PHP namespace App\Models; use Workflow\Models\StoredWorkflow as BaseStoredWorkflow; class StoredWorkflow extends BaseStoredWorkflow { protected $connection = 'mysql'; } ``` ```PHP namespace App\Models; use Workflow\Models\StoredWorkflowException as BaseStoredWorkflowException; class StoredWorkflowException extends BaseStoredWorkflowException { protected $connection = 'mysql'; } ``` ```PHP namespace App\Models; use Workflow\Models\StoredWorkflowLog as BaseStoredWorkflowLog; class StoredWorkflowLog extends BaseStoredWorkflowLog { protected $connection = 'mysql'; } ``` ```PHP namespace App\Models; use Workflow\Models\StoredWorkflowSignal as BaseStoredWorkflowSignal; class StoredWorkflowSignal extends BaseStoredWorkflowSignal { protected $connection = 'mysql'; } ``` ```PHP namespace App\Models; use Workflow\Models\StoredWorkflowTimer as BaseStoredWorkflowTimer; class StoredWorkflowTimer extends BaseStoredWorkflowTimer { protected $connection = 'mysql'; } ``` -------------------------------- ### Implement Side Effect in Laravel Workflow with PHP Source: https://laravel-workflow.com/features/side-effects This example demonstrates how to use `WorkflowStub::sideEffect` within a Laravel Workflow. It shows a non-deterministic function, `random_int()`, being executed inside a side effect closure. The result of this closure is saved and reused if the workflow is retried, ensuring the random value is generated only once. ```php use Workflow\Workflow; use Workflow\WorkflowStub; class MyWorkflow extends Workflow { public function execute() { $seconds = yield WorkflowStub::sideEffect(fn () => random_int(60, 120)); yield WorkflowStub::timer($seconds); } } ``` -------------------------------- ### Access Workflow ID within an Activity Source: https://laravel-workflow.com/defining-workflows/workflow-id This example illustrates how an activity can access the ID of the workflow it belongs to using `$this->workflowId()`. This capability is vital for activities that need to store or retrieve workflow-specific data in external systems, such as a cache or database, ensuring that the information is correctly associated with the executing workflow instance. ```php use Illuminate\Support\Facades\Cache; use Workflow\Activity; class MyActivity extends Activity { public function execute() { $workflowId = $this->workflowId(); // Use the workflow id to store data in a cache or database Cache::put("workflow:{$workflowId}:data", 'some data'); } } ``` -------------------------------- ### Run Workflow and Activity Tests in Laravel Source: https://laravel-workflow.com/sample-app This command executes the automated tests for the workflows and activities within the Laravel sample application. It verifies the correct functionality and integration of the implemented workflows and their associated activities. ```bash php artisan test ``` -------------------------------- ### Define a Basic Laravel Workflow for Testing Source: https://laravel-workflow.com/testing This PHP code defines a simple Laravel Workflow class, `MyWorkflow`, which executes an activity using `ActivityStub::make()` and returns its result. This workflow serves as a base for demonstrating testing methodologies. ```PHP use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute() { $result = yield ActivityStub::make(MyActivity::class); return $result; } } ``` -------------------------------- ### Testing Laravel Workflow Activities by Calling handle() Source: https://laravel-workflow.com/testing This PHP code snippet demonstrates how to test a Laravel Workflow activity. It involves creating a WorkflowStub, instantiating the specific activity class with its required constructor arguments, and then directly calling the `handle()` method on the activity instance to execute its logic. It explicitly notes that the `handle()` method is called, not `execute()`. ```PHP $workflow = WorkflowStub::make(MyWorkflow::class); $activity = new MyActivity(0, now()->toDateTimeString(), StoredWorkflow::findOrFail($workflow->id())); $result = $activity->handle(); ``` -------------------------------- ### Query a Workflow Instance in Laravel Workflow Source: https://laravel-workflow.com/features/queries Demonstrates how to load a workflow stub by its ID and then call a defined query method on it. The query method will return the current state data from the workflow without advancing its execution. ```php use Workflow\WorkflowStub; $workflow = WorkflowStub::load($workflowId); $ready = $workflow->getReady(); ``` -------------------------------- ### Configuring Activity Options in Laravel Workflow Source: https://laravel-workflow.com/configuration/options This PHP code defines a `MyActivity` class extending `Workflow\Activity`, showcasing how to set properties like `$connection`, `$queue`, `$tries`, and `$timeout` for controlling queue behavior, retries, and execution limits. It also demonstrates implementing the `backoff()` method to define custom retry delays. ```php use Workflow\Activity; class MyActivity extends Activity { public $connection = 'default'; public $queue = 'default'; public $tries = 0; public $timeout = 0; public function backoff() { return [1, 2, 5, 10, 15, 30, 60, 120]; } } ``` -------------------------------- ### Workflow and Activity Constraints Summary Source: https://laravel-workflow.com/constraints/constraints-summary This table summarizes the key constraints that apply to Workflows and Activities within the Laravel Workflow system, indicating what is disallowed (❌) and allowed (✔️) for each category. ```APIDOC | Workflows | Activities | | --- | --- | | ❌ IO | ✔️ IO | | ❌ mutable global variables | ✔️ mutable global variables | | ❌ non-deterministic functions | ✔️ non-deterministic functions | | ❌ `Carbon::now()` | ✔️ `Carbon::now()` | | ❌ `sleep()` | ✔️ `sleep()` | | ❌ non-idempotent | ❌ non-idempotent | ``` -------------------------------- ### Define a Laravel Activity to Receive Data Source: https://laravel-workflow.com/defining-workflows/passing-data Shows how to define an `Activity` class with an `execute` method that accepts arguments and uses them to return a dynamic string. ```PHP use Workflow\Activity; class MyActivity extends Activity { public function execute($name) { return "Hello, {$name}!"; } } ``` -------------------------------- ### Configure Shared MySQL, Redis, and Queue Connections in Laravel Source: https://laravel-workflow.com/configuration/microservices This snippet demonstrates how to define a 'shared' MySQL database connection and a 'shared' Redis connection within Laravel's `config/database.php` file. It also includes the configuration for a 'shared' Redis-based queue connection in `config/queue.php`, enabling inter-microservice communication. ```php 'connections' => [ 'shared' => [ 'driver' => 'mysql', 'url' => env('SHARED_DB_URL'), 'host' => env('SHARED_DB_HOST', '127.0.0.1'), 'port' => env('SHARED_DB_PORT', '3306'), 'database' => env('SHARED_DB_DATABASE', 'laravel'), 'username' => env('SHARED_DB_USERNAME', 'root'), 'password' => env('SHARED_DB_PASSWORD', ''), 'unix_socket' => env('SHARED_DB_SOCKET', ''), 'charset' => env('SHARED_DB_CHARSET', 'utf8mb4'), 'collation' => env('SHARED_DB_COLLATION', 'utf8mb4_unicode_ci'), 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('SHARED_MYSQL_ATTR_SSL_CA'), ]) : [], ], ], 'redis' => [ 'shared' => [ 'url' => env('SHARED_REDIS_URL'), 'host' => env('SHARED_REDIS_HOST', '127.0.0.1'), 'username' => env('SHARED_REDIS_USERNAME'), 'password' => env('SHARED_REDIS_PASSWORD'), 'port' => env('SHARED_REDIS_PORT', '6379'), 'database' => env('SHARED_REDIS_DB', '0'), ], ], ``` ```php 'connections' => [ 'shared' => [ 'driver' => 'redis', 'connection' => env('SHARED_REDIS_QUEUE_CONNECTION', 'default'), 'queue' => env('SHARED_REDIS_QUEUE', 'default'), 'retry_after' => (int) env('SHARED_REDIS_QUEUE_RETRY_AFTER', 90), 'block_for' => null, 'after_commit' => false, ], ], ``` -------------------------------- ### Run Laravel Queue Workers for Shared Connections Source: https://laravel-workflow.com/configuration/microservices These commands demonstrate how to run Laravel queue workers in each microservice, specifying the 'shared' connection and their respective unique queue names ('workflow' and 'activity'). This ensures that each microservice processes jobs from its designated queue. ```bash php artisan queue:work shared --queue=workflow php artisan queue:work shared --queue=activity ``` -------------------------------- ### Typical Workflow Event Lifecycle Source: https://laravel-workflow.com/features/events Illustrates the standard sequence of events during a successful workflow execution, from its initiation to its final completion. ```text Workflow\Events\WorkflowStarted Workflow\Events\ActivityStarted Workflow\Events\ActivityCompleted Workflow\Events\WorkflowCompleted ``` -------------------------------- ### Test Workflow Pruning with Pretend Option Source: https://laravel-workflow.com/configuration/pruning-workflows To safely test the `model:prune` command without actually deleting any records, use the `--pretend` option. This will report how many records would be pruned if the command were to run. ```bash php artisan model:prune --model="Workflow\Models\StoredWorkflow" --pretend ``` -------------------------------- ### Test Laravel Workflow by Mocking Activity with Callback Source: https://laravel-workflow.com/testing This PHP test shows how to mock an activity in a Laravel Workflow using a callback function. The callback receives the workflow context and activity arguments, allowing for dynamic result generation, and the test asserts the workflow's output. ```PHP public function testWorkflow() { WorkflowStub::fake(); WorkflowStub::mock(MyActivity::class, function ($context) { return 'result'; }); $workflow = WorkflowStub::make(MyWorkflow::class); $workflow->start(); $this->assertSame($workflow->output(), 'result'); } ``` -------------------------------- ### Generate Workflow and Activity Files Source: https://laravel-workflow.com/configuration/publishing-config These Artisan commands create new workflow and activity classes. By default, they are placed in the `app/Workflows` folder, which can be customized via configuration. ```php php artisan make:workflow MyWorkflow php artisan make:activity MyActivity ``` -------------------------------- ### Define a Laravel Workflow to Receive Data Source: https://laravel-workflow.com/defining-workflows/passing-data Illustrates how to define a `Workflow` class with an `execute` method that accepts arguments. This method then passes the received data to an `ActivityStub`. ```PHP use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute($name) { return yield ActivityStub::make(MyActivity::class, $name); } } ``` -------------------------------- ### Test Laravel Workflow by Mocking Activity with Static Result Source: https://laravel-workflow.com/testing This PHP test demonstrates how to synchronously test a Laravel Workflow. It uses `WorkflowStub::fake()` to enable testing mode and `WorkflowStub::mock()` to provide a static 'result' for `MyActivity`, then asserts the workflow's output. ```PHP public function testWorkflow() { WorkflowStub::fake(); WorkflowStub::mock(MyActivity::class, 'result'); $workflow = WorkflowStub::make(MyWorkflow::class); $workflow->start(); $this->assertSame($workflow->output(), 'result'); } ``` -------------------------------- ### Generate a new Laravel Workflow Activity Source: https://laravel-workflow.com/defining-workflows/activities Use the Artisan command to quickly scaffold a new activity class file in your Laravel project. ```php php artisan make:activity MyActivity ``` -------------------------------- ### Define a Laravel Workflow Class with Activity Stub Source: https://laravel-workflow.com/defining-workflows/workflows This PHP code snippet illustrates the basic structure of a Laravel Workflow class. It extends the `Workflow` base class and implements the `execute()` method, where the `yield` keyword is used with `ActivityStub::make()` to pause execution and wait for an activity's completion, demonstrating how activities are integrated into a workflow. ```php use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute() { $result = yield ActivityStub::make(MyActivity::class); return $result; } } ``` -------------------------------- ### Registering Laravel Workflow Webhook Routes Source: https://laravel-workflow.com/features/webhooks This PHP snippet demonstrates how to enable webhook functionality in a Laravel application by registering the necessary routes using `Webhooks::routes()`. This should be placed in `routes/web.php` or `routes/api.php`. ```php use Workflow\Webhooks; Webhooks::routes(); ``` -------------------------------- ### Configure Laravel Workflow Activity for Immediate Exception Reporting Source: https://laravel-workflow.com/failures-and-recovery This PHP code snippet demonstrates how to configure a Laravel Workflow Activity to immediately inform the workflow when an exception occurs. By setting the "$tries" property to "1", the activity will not retry upon failure, sending the exception directly to the workflow for handling. ```PHP use Exception; use Workflow\Activity; class MyActivity extends Activity { public $tries = 1; public function execute() { throw new Exception(); } } ``` -------------------------------- ### Inject Dependencies into a Laravel Workflow Source: https://laravel-workflow.com/defining-workflows/passing-data Demonstrates how to use Laravel's service container to automatically inject dependencies, such as the `Application` contract, into a workflow's `execute` method by type-hinting. ```PHP use Illuminate\Contracts\Foundation\Application; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute(Application $app) { if ($app->runningInConsole()) { // ... } } } ``` -------------------------------- ### Define a Query Method in Laravel Workflow Source: https://laravel-workflow.com/features/queries Illustrates how to define a query method on a workflow using the `QueryMethod` annotation. This method allows retrieving the workflow's internal state without affecting its execution, useful for monitoring and debugging. ```php use Workflow\QueryMethod; use Workflow\Workflow; class MyWorkflow extends Workflow { private bool $ready = false; #[QueryMethod] public function getReady(): bool { return $this->ready; } } ``` -------------------------------- ### Define Workflow with Signal and Timeout Await Source: https://laravel-workflow.com/features/signal+timer This PHP code defines a `MyWorkflow` class that extends `Workflow`. It includes a `setReady` signal method to update an internal state and an `execute` method that uses `WorkflowStub::awaitWithTimeout` to wait for either the `$ready` state to become true or a 5-minute timeout to expire, whichever occurs first. The `awaitWithTimeout` method returns `true` if the signal was received, or `false` if the timeout was reached. ```PHP use Workflow\SignalMethod; use Workflow\Workflow; use Workflow\WorkflowStub; class MyWorkflow extends Workflow { private bool $ready = false; #[SignalMethod] public function setReady($ready) { $this->ready = $ready } public function execute() { // Wait for 5 minutes or $ready = true, whichever comes first $result = yield WorkflowStub::awaitWithTimeout(300, fn () => $this->ready); } } ``` -------------------------------- ### Assert Dispatched Activities and Child Workflows in Laravel Source: https://laravel-workflow.com/testing This PHP code demonstrates various assertion methods provided by `WorkflowStub` to verify which activities or child workflows were dispatched during a workflow's execution. It includes asserting dispatch, asserting dispatch count, asserting not dispatched, and asserting nothing dispatched. ```PHP WorkflowStub::assertDispatched(MyActivity::class); // Assert the activity was dispatched twice... WorkflowStub::assertDispatched(MyActivity::class, 2); WorkflowStub::assertNotDispatched(MyActivity::class); WorkflowStub::assertNothingDispatched(); ``` -------------------------------- ### Configure Workflow Data Serializer Source: https://laravel-workflow.com/configuration/publishing-config This setting specifies the serializer used for workflow data. The `Y` serializer is default, offering smaller size, while `Base64` provides faster serialization with more overhead. Changing this only affects new workflows. ```php 'serializer' => Workflow\Serializers\Y::class, ``` ```php 'serializer' => Workflow\Serializers\Base64::class, ``` -------------------------------- ### Define Mixed Serial and Parallel Workflow Execution in Laravel Source: https://laravel-workflow.com/features/concurrency This PHP code snippet illustrates a Laravel Workflow definition that combines serial and parallel activity executions. It uses `ActivityStub::make` for sequential tasks, `ActivityStub::all` to run multiple tasks concurrently, and `ActivityStub::async` to encapsulate a series of tasks that run asynchronously alongside other parallel tasks. This pattern allows for fine-grained control over the order and concurrency of workflow activities. ```php use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute() { return [ yield ActivityStub::make(MyActivity1::class), yield ActivityStub::all([ ActivityStub::async(fn () => [ yield ActivityStub::make(MyActivity2::class), yield ActivityStub::make(MyActivity3::class), ]), ActivityStub::make(MyActivity4::class), ActivityStub::make(MyActivity5::class), ]), yield ActivityStub::make(MyActivity6::class), ]; } } ``` -------------------------------- ### Generate HMAC Signature and Send Authenticated Request Source: https://laravel-workflow.com/features/webhooks Shows how to generate an HMAC-SHA256 signature for a request body using OpenSSL and include it in the `X-Signature` header for authentication with Laravel Workflow webhooks. ```bash BODY='{"orderId": 123}' SIGNATURE=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "your-secret-key" | awk '{print $2}') curl -X POST "https://example.com/webhooks/start/order-workflow" \ -H "Content-Type: application/json" \ -H "X-Signature: $SIGNATURE" \ -d "$BODY" ``` -------------------------------- ### Maintain Empty Duplicate Workflow Class (Activity Microservice) Source: https://laravel-workflow.com/configuration/microservices This snippet shows an empty duplicate `MyWorkflow` class in the activity microservice. This is crucial for maintaining consistent namespaces and class names across microservices, preventing exceptions due to class discrepancies, even if the actual workflow logic resides elsewhere. ```php use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public $connection = 'shared'; public $queue = 'workflow'; } ``` -------------------------------- ### Publish Laravel Workflow Configuration File Source: https://laravel-workflow.com/configuration/publishing-config This Artisan command publishes the default `workflows.php` configuration file to your `config` directory, enabling customization of Laravel Workflow's settings. ```php php artisan vendor:publish --provider="Workflow\Providers\WorkflowServiceProvider" --tag="config" ``` -------------------------------- ### Webhook Endpoint for Sending a Signal Source: https://laravel-workflow.com/features/webhooks This API endpoint specifies the HTTP method and URL path for sending the `mark-as-shipped` signal to a specific `order-workflow` instance, identified by its `{workflowId}`, via a webhook. ```APIDOC POST /webhooks/signal/order-workflow/{workflowId}/mark-as-shipped ``` -------------------------------- ### Define a Time-Dependent Laravel Workflow with Timer Source: https://laravel-workflow.com/testing This PHP code defines `MyTimerWorkflow`, a Laravel Workflow that uses `WorkflowStub::timer()` to introduce a 60-second delay before executing an activity. This workflow is designed to demonstrate testing time-sensitive logic. ```PHP use Workflow\ActivityStub; use Workflow\Workflow; use Workflow\WorkflowStub; class MyTimerWorkflow extends Workflow { public function execute() { yield WorkflowStub::timer(60); $result = yield ActivityStub::make(MyActivity::class); return $result; } } ``` -------------------------------- ### Maintain Empty Duplicate Activity Class (Workflow Microservice) Source: https://laravel-workflow.com/configuration/microservices This snippet shows an empty duplicate `MyActivity` class in the workflow microservice. This is crucial for maintaining consistent namespaces and class names across microservices, preventing exceptions due to class discrepancies, even if the actual activity logic resides elsewhere. ```php use Workflow\Activity; class MyActivity extends Activity { public $connection = 'shared'; public $queue = 'activity'; } ``` -------------------------------- ### Workflow Event Lifecycle with Activity Failure and Recovery Source: https://laravel-workflow.com/features/events Shows the sequence of events when an activity within a workflow initially fails but then successfully recovers, allowing the overall workflow to proceed to completion. ```text Workflow\Events\WorkflowStarted Workflow\Events\ActivityStarted Workflow\Events\ActivityFailed Workflow\Events\ActivityStarted Workflow\Events\ActivityCompleted Workflow\Events\WorkflowCompleted ``` -------------------------------- ### Define Custom Workflow Pruning Logic Source: https://laravel-workflow.com/configuration/pruning-workflows For more granular control over which workflows are pruned, you can extend the base workflow model and implement your own `prunable` method. This method should return a query builder instance that defines the conditions for pruning. ```php public function prunable(): Builder { return static::where('status', 'completed') ->where('created_at', '<=', now()->subMonth()) ->whereDoesntHave('parents'); } ``` -------------------------------- ### Run Artisan Command to Prune Workflows Source: https://laravel-workflow.com/configuration/pruning-workflows To periodically delete completed workflows that are no longer needed, use the `model:prune` Artisan command. This command targets `Workflow\Models\StoredWorkflow` by default. ```bash php artisan model:prune --model="Workflow\Models\StoredWorkflow" ``` -------------------------------- ### Implement a Saga Workflow for Distributed Transactions in Laravel Workflow Source: https://laravel-workflow.com/features/sagas This PHP code defines a `BookingSagaWorkflow` class that demonstrates the Saga pattern. It orchestrates a series of booking activities (flight, hotel, car rental) and registers compensation activities for each. If any activity fails, the `compensate()` method is called to undo previously completed work, ensuring atomicity in distributed transactions. ```PHP use Workflow\ActivityStub; use Workflow\Workflow; class BookingSagaWorkflow extends Workflow { public function execute() { try { $flightId = yield ActivityStub::make(BookFlightActivity::class); $this->addCompensation(fn () => ActivityStub::make(CancelFlightActivity::class, $flightId)); $hotelId = yield ActivityStub::make(BookHotelActivity::class); $this->addCompensation(fn () => ActivityStub::make(CancelHotelActivity::class, $hotelId)); $carId = yield ActivityStub::make(BookRentalCarActivity::class); $this->addCompensation(fn () => ActivityStub::make(CancelRentalCarActivity::class, $carId)); } catch (Throwable $th) { yield from $this->compensate(); throw $th; } } } ``` -------------------------------- ### Extend Laravel Workflow Models for Shared Database Source: https://laravel-workflow.com/configuration/microservices This snippet illustrates how to extend the base Laravel Workflow models, such as `StoredWorkflow`, to explicitly use the 'shared' database connection. This ensures that workflow data is read from and written to the central shared database across all microservices. ```php class StoredWorkflow extends BaseStoredWorkflow { protected $connection = 'shared'; ``` -------------------------------- ### Configure Custom Workflow Models Source: https://laravel-workflow.com/configuration/publishing-config Customize the Eloquent models used by Laravel Workflow for storing various workflow-related data, such as stored workflows, exceptions, logs, signals, and timers, by updating these settings in `workflows.php`. ```php 'stored_workflow_model' => App\Models\StoredWorkflow::class, 'stored_workflow_exception_model' => App\Models\StoredWorkflowException::class, 'stored_workflow_log_model' => App\Models\StoredWorkflowLog::class, 'stored_workflow_signal_model' => App\Models\StoredWorkflowSignal::class, 'stored_workflow_timer_model' => App\Models\StoredWorkflowTimer::class, ``` -------------------------------- ### Configure Custom Workflows Folder Path Source: https://laravel-workflow.com/configuration/publishing-config Update the `workflows_folder` setting in your `workflows.php` configuration file to specify a custom directory where workflow and activity files should be generated by Artisan commands. ```php 'workflows_folder' => 'Workflows', ``` -------------------------------- ### List All Possible Laravel Workflow Status Values Source: https://laravel-workflow.com/defining-workflows/workflow-status This snippet provides a comprehensive list of all possible status values that a Laravel workflow can return when its `status()` method is called. These values represent different stages in the workflow's lifecycle. ```php WorkflowCreatedStatus WorkflowCompletedStatus WorkflowFailedStatus WorkflowPendingStatus WorkflowRunningStatus WorkflowWaitingStatus ``` -------------------------------- ### Define a Laravel Workflow Activity Class Source: https://laravel-workflow.com/defining-workflows/activities Activities are defined by extending the `Workflow\Activity` class and implementing the `execute()` method, which encapsulates the specific task or operation to be performed by the workflow. ```php use Workflow\Activity; class MyActivity extends Activity { public function execute() { // Perform some work... return $result; } } ``` -------------------------------- ### Pass Eloquent Models to a Laravel Workflow Source: https://laravel-workflow.com/defining-workflows/passing-data Demonstrates how to type-hint and pass an Eloquent `User` model directly into a workflow's `execute` method. The workflow then extracts a property (`name`) from the model to pass to an activity. ```PHP use App\Models\User; use Workflow\ActivityStub; use Workflow\Workflow; class MyWorkflow extends Workflow { public function execute(User $user) { return yield ActivityStub::make(MyActivity::class, $user->name); } } ``` -------------------------------- ### WebhookAuthenticator Interface API Reference Source: https://laravel-workflow.com/features/webhooks API documentation for the `WebhookAuthenticator` interface, detailing its `validate` method which is used for custom webhook authentication in Laravel Workflow. ```APIDOC WebhookAuthenticator interface: validate(request: Illuminate\Http\Request): Illuminate\Http\Request request: The incoming HTTP request to validate. Returns: The validated Request object if successful, otherwise calls abort(401) for unauthorized access. ``` -------------------------------- ### Send POST Request with Token Authentication Source: https://laravel-workflow.com/features/webhooks Demonstrates how to send a POST request to a Laravel Workflow webhook endpoint using a bearer token for authentication. The request includes a JSON payload. ```bash curl -X POST "https://example.com/webhooks/start/order-workflow" \ -H "Content-Type: application/json" \ -H "Authorization: your-api-token" \ -d '{"orderId": 123}' ``` -------------------------------- ### Signal a Workflow to Continue Source: https://laravel-workflow.com/features/signal+timer This PHP snippet demonstrates how to signal an active workflow instance to continue its execution by calling its `setReady` method. This will cause the `awaitWithTimeout` call within the workflow to resolve, provided the timeout has not yet been reached. The timeout can also be specified as a string like '30 seconds' or '5 minutes'. ```PHP $workflow->setReady(); ``` -------------------------------- ### Configure Custom Webhook Authenticator in Laravel Workflows Source: https://laravel-workflow.com/features/webhooks Illustrates how to configure the `config/workflows.php` file to use a custom webhook authenticator class, setting the authentication method to 'custom' and specifying the class path. ```php 'webhook_auth' => [ 'method' => 'custom', 'custom' => [ 'class' => App\Your\CustomAuthenticator::class, ], ], ``` -------------------------------- ### APIDOC: ActivityCompleted Event in Laravel Workflow Source: https://laravel-workflow.com/features/events Documents the ActivityCompleted event, dispatched when an activity successfully finishes, including its parent workflow ID, activity ID, output, and completion timestamp. ```APIDOC ActivityCompleted: Attributes: workflowId: The ID of the parent workflow. activityId: Unique identifier for the activity. output: The result returned by the activity. timestamp: Timestamp of when the activity completed. ``` -------------------------------- ### APIDOC: ActivityFailed Event in Laravel Workflow Source: https://laravel-workflow.com/features/events Documents the ActivityFailed event, triggered when an activity fails during execution, providing its parent workflow ID, activity ID, error details, and failure timestamp. ```APIDOC ActivityFailed: Attributes: workflowId: The ID of the parent workflow. activityId: Unique identifier for the activity. output: Error message or exception details. timestamp: Timestamp of when the activity failed. ``` -------------------------------- ### Invoking Child Workflows in Laravel Source: https://laravel-workflow.com/features/child-workflows This snippet demonstrates how to define a parent workflow that invokes a child workflow. Child workflows are regular workflows that are called using `ChildWorkflowStub::make()` within the parent's `execute` method, allowing for modular and hierarchical workflow design. ```PHP use Workflow\ChildWorkflowStub; use Workflow\Workflow; class ParentWorkflow extends Workflow { public function execute() { $childResult = yield ChildWorkflowStub::make(ChildWorkflow::class); } } ``` -------------------------------- ### Define a Signal Method in Laravel Workflow Source: https://laravel-workflow.com/features/signals This PHP code demonstrates how to define a signal method within a Laravel Workflow class using the `SignalMethod` annotation. The `setReady` method, when signaled, updates the `$ready` property, allowing external events to modify workflow state. ```php use Workflow\SignalMethod; use Workflow\Workflow; class MyWorkflow extends Workflow { protected $ready = false; #[SignalMethod] public function setReady($ready) { $this->ready = $ready; } } ``` -------------------------------- ### Test Time-Dependent Laravel Workflow with Time Travel Source: https://laravel-workflow.com/testing This PHP test demonstrates how to simulate time progression in a Laravel Workflow using `$this->travel()`. It allows skipping waiting periods introduced by `WorkflowStub::timer()` and resuming the workflow to test time-sensitive logic efficiently. ```PHP public function testTimeTravelWorkflow() { WorkflowStub::fake(); WorkflowStub::mock(MyActivity::class, 'result'); $workflow = WorkflowStub::make(MyTimerWorkflow::class); $workflow->start(); $this->travel(120)->seconds(); $workflow->resume(); $this->assertSame($workflow->output(), 'result'); } ``` -------------------------------- ### APIDOC: WorkflowCompleted Event in Laravel Workflow Source: https://laravel-workflow.com/features/events Documents the WorkflowCompleted event, triggered upon successful completion of a workflow, including its unique ID, output, and completion timestamp. ```APIDOC WorkflowCompleted: Attributes: workflowId: Unique identifier for the workflow. output: The result returned by the workflow. timestamp: Timestamp of when the workflow completed. ``` -------------------------------- ### APIDOC: WorkflowFailed Event in Laravel Workflow Source: https://laravel-workflow.com/features/events Documents the WorkflowFailed event, dispatched when a workflow encounters an error during execution, providing the workflow ID, error details, and failure timestamp. ```APIDOC WorkflowFailed: Attributes: workflowId: Unique identifier for the workflow. output: Error message or exception details. timestamp: Timestamp of when the workflow failed. ``` -------------------------------- ### Define a Non-Retryable Exception in Laravel Workflow Activity Source: https://laravel-workflow.com/failures-and-recovery This PHP snippet shows how to define an activity that throws a "NonRetryableException". When this type of exception is thrown, the Laravel Workflow will immediately mark the activity as failed and cease any further retry attempts, indicating a permanent failure that requires manual intervention. ```PHP use Workflow\Activity; use Workflow\Exceptions\NonRetryableException; class MyNonRetryableActivity extends Activity { public function execute() { throw new NonRetryableException('This is a non-retryable error'); } } ``` -------------------------------- ### Serialized Laravel Eloquent Model Identifier Structure Source: https://laravel-workflow.com/defining-workflows/passing-data Illustrates the structure of the `ModelIdentifier` object that is serialized when an Eloquent model is passed to a workflow or activity. It shows the `id`, `class`, `relations`, and `connection` properties. ```PHP object(ModelIdentifier) { id: 42, class: "App\Models\User", relations: [], connection: "mysql" } ``` -------------------------------- ### Modify Laravel Workflow Migration for Shared Database Source: https://laravel-workflow.com/configuration/microservices This code snippet demonstrates how to modify a Laravel Workflow migration file to use the designated 'shared' database connection. By setting the `$connection` property, the migration will apply schema changes to the shared database, ensuring consistency across microservices. ```php final class CreateWorkflowsTable extends Migration { protected $connection = 'shared'; ``` -------------------------------- ### Configure Base Model for Workflow Entities Source: https://laravel-workflow.com/configuration/publishing-config This setting defines the base Eloquent model that Laravel Workflow's internal models extend. It can be changed to support custom Eloquent implementations, such as those required by specific database drivers like MongoDB. ```php 'base_model' => Illuminate\Database\Eloquent\Model::class, ``` ```php 'base_model' => MongoDB\Laravel\Eloquent\Model::class, ``` -------------------------------- ### Monitor Laravel Workflow Running Status Source: https://laravel-workflow.com/defining-workflows/workflow-status This snippet demonstrates how to continuously check if a Laravel workflow is still running using the `running()` method. The method returns `true` if the workflow is active and `false` if it has completed or failed. ```php while ($workflow->running()); ```