PHP Classes

File: demo/README.md

Recommend this page to a friend!
  Classes of Rodolfo Berrios Arce   Workflow   demo/README.md   Download  
File: demo/README.md
Role: Documentation
Content type: text/markdown
Description: Documentation
Class: Workflow
Create and run action workflows
Author: By
Last change:
Date: 1 month ago
Size: 5,622 bytes
 

Contents

Class file image Download

Demo

Hello, world

Run live example: php demo/hello-world.php Rodolfo - view source

The basic example Workflow defines a greet for a given username. The job greet is a named argument and it takes the GreetAction plus its main method arguments. The run function is used to execute the Workflow.

use Chevere\Demo\Actions\Greet;
use function Chevere\Workflow\run;
use function Chevere\Workflow\sync;
use function Chevere\Workflow\variable;
use function Chevere\Workflow\workflow;

$workflow = workflow(
    greet: sync(
        new Greet(),
        username: variable('username'),
    ),
);
$run = run(
    $workflow,
    username: $argv[1] ?? 'World'
);
$greet = $run->response('greet')->string();
echo <<<PLAIN
{$greet}

PLAIN;

The graph for this Workflow contains only the greet job.

$workflow->jobs()->graph()->toArray();
// contains
[
    ['greet'],
];

Image resize example (async)

Run live example: php demo/image-resize.php - view source

For this example Workflow defines an image resize procedure in two sizes. All jobs are defined as async, but as there are dependencies between jobs (see variable and response) the system resolves a suitable run strategy.

use Chevere\Demo\Actions\ImageResize;
use Chevere\Demo\Actions\StoreFile;
use function Chevere\Workflow\async;
use function Chevere\Workflow\response;
use function Chevere\Workflow\run;
use function Chevere\Workflow\variable;
use function Chevere\Workflow\workflow;

$workflow = workflow(
    thumb: async(
        new ImageResize(),
        file: variable('image'),
        fit: 'thumbnail',
    ),
    poster: async(
        new ImageResize(),
        file: variable('image'),
        fit: 'poster',
    ),
    storeThumb: async(
        new StoreFile(),
        file: response('thumb'),
        dir: variable('saveDir'),
    ),
    storePoster: async(
        new StoreFile(),
        file: response('poster'),
        dir: variable('saveDir'),
    )
);
$run = run(
    $workflow,
    image: __DIR__ . '/src/php.jpeg',
    saveDir: __DIR__ . '/src/output/',
);

The graph for the Workflow above shows that thumb and poster run async, just like storeThumb and storePoster but the store* jobs run after the first dependency level gets resolved.

graph TD;
    thumb-->storeThumb;
    poster-->storePoster;

$workflow->jobs()->graph()->toArray();
// contains
[
    ['thumb', 'poster'],
    ['storeThumb', 'storePoster']
];

Use function run to run the Workflow, variables are passed as named arguments.

use function Chevere\Workflow\run;

$run = run(
    $workflow,
    image: '/path/to/image-to-upload.png',
    savePath: '/path/to/storage/'
);

Use response to retrieve a job response as a CastArgument object which can be used to get a typed response.

$thumbFile = $run->response('thumb')->string();

If the response is of type array you can wrap using cast as needed.

use function Chevere\Parameter\cast;

$id = $run->response('user')->array()['id']; // ? type
$id = cast($id)->int(); // int type

Sync vs Async

Run live example: php demo/sync-vs-async.php - view source

For this example you can compare the execution time between synchronous and asynchronous jobs. The example fetches the content of three URLs using FetchUrl action.

use Chevere\Demo\Actions\FetchUrl;
use function Chevere\Workflow\async;
use function Chevere\Workflow\run;
use function Chevere\Workflow\sync;
use function Chevere\Workflow\variable;
use function Chevere\Workflow\workflow;

$sync = workflow(
    j1: sync(
        new FetchUrl(),
        url: variable('php'),
    ),
    j2: sync(
        new FetchUrl(),
        url: variable('github'),
    ),
    j3: sync(
        new FetchUrl(),
        url: variable('chevere'),
    ),
);
$async = workflow(
    j1: async(
        new FetchUrl(),
        url: variable('php'),
    ),
    j2: async(
        new FetchUrl(),
        url: variable('github'),
    ),
    j3: async(
        new FetchUrl(),
        url: variable('chevere'),
    ),
);
$variables = [
    'php' => 'https://www.php.net',
    'github' => 'https://github.com/chevere/workflow',
    'chevere' => 'https://chevere.org',
];
$time = microtime(true);
$run = run($sync, ...$variables);
$time = round((microtime(true) - $time) * 1000);
echo "Time (ms)  sync: {$time}\n";

$time = microtime(true);
$run = run($async, ...$variables);
$time = round((microtime(true) - $time) * 1000);
echo "Time (ms) async: {$time}\n";

When running sync (blocking) jobs the execution time is higher than async (non-blocking) jobs. This is because async jobs run in parallel.

Time (ms)  sync: 2307
Time (ms) async: 1119

Conditional jobs

Run live example: php demo/run-if.php - view source

For this example Workflow defines a greet for a given username, but only if a sayHello variable is set to true.

use Chevere\Demo\Actions\Greet;
use function Chevere\Workflow\run;
use function Chevere\Workflow\sync;
use function Chevere\Workflow\variable;
use function Chevere\Workflow\workflow;

/*
php demo/run-if.php Rodolfo
php demo/run-if.php
*/

$workflow = workflow(
    greet: sync(
        new Greet(),
        username: variable('username'),
    )->withRunIf(
        variable('sayHello')
    ),
);

Method withRunIf accepts one or more variable and response references. All conditions must be true at the same time for the job to run.