Skip to content

schrobak/assistant

Repository files navigation

Revolve Assistant

Status Quality Coverage License

Testing

$ git@github.com:revolvephp/assistant.git
$ cd assistant
$ vendor/bin/phpunit

Installing

$ composer require "revolvephp/assistant:dev-master"

This is not stable or tested enough to tag a release. Sorry folks!

Tasks and Messengers

use League\Event\Event;
use Revolve\Assistant\Make;
use Revolve\Assistant\Task\TaskInterface;

$make = new Make();

$messenger = $make->messenger([
    "provider" => "memcached",
    "memcached" => [
        "namespace" => "assistant",
        "servers" => [
            ["127.0.0.1", 11211],
        ],
    ],
    "iron" => [
        "namespace" => "assistant",
        "token" => getenv("IRON_TOKEN"),
        "project" => getenv("IRON_PROJECT"),
    ],
]);

$task = $make->task([
    "provider" => "gearman",
    "gearman" => [
        "closure" => function(TaskInterface $task) use ($messenger) {
            print "see this in the worker output";

            $task->writeTo($messenger, "output", "see this in the client output");
        },
    ],
]);

$task->addListener("output", function(Event $event, $message) {
    print $message;
});

Workers

use Revolve\Assistant\Make;

$make = new Make();

$worker = $make->worker([
    "provider" => "gearman",
    "gearman" => [
        "namespace" => "assistant",
        "servers" => [
            ["127.0.0.1", 4730],
        ],
    ],
]);

$worker->run(); // infinite loop, which is ok for the worker!

Clients

use Revolve\Assistant\Make;

$make = new Make();

$task = $make->task(...);

$client = $make->client([
    "provider" => "gearman",
    "gearman" => [
        "namespace" => "assistant",
        "servers" => [
            ["127.0.0.1", 4730],
        ],
    ]
]);

$client->handle($task);

do {
    $client->read($messenger);

    print ".";

    if ($client->hasCompleted($task)) {
        break;
    }

    usleep(50000);
} while (true);

// infinite loop, which is not ok for the client! Use an event loop instead...

Fire-and-forget tasks

use Revolve\Assistant\Make;

$make = new Make();

$client = $make->client(...)->handle(
    $make->task(...)
);

// fire-and-forget tasks don't need event listeners
// ...or $client->read() or $client->hasCompleted()

Flow

flow

Answers

What is this?

It's an abstraction for non-blocking tools and workflows. It's a wrapper around concurrent, asynchronous extensions like Gearman, IronWorker, pThreads and pcntl_fork.

Why not use queues?

Queues are a different thing. They are often used to get blocking tasks out of the request/response cycle, but they are uni-directional. There's no way to get progress or completion events.

What are messengers for?

Many concurrent, asynchronous extensions/libraries don't let you communicate from the worker back to the manager. Some allow you to wait until the worker is done, but that's blocking and poorly supported. The messenger allows this communication is a non-blocking way.

Infinite loops are blocking, chump!

That's not a question.

The examples use infinite loops, and these are blocking. For optimal results, you should use Assistant within an event loop. I built it to work with the framework, but it works like a charm with any React app.

Roadmap

  • Add tests
  • Add MessengerInterface providers: Filesystem, ZeroMQ
  • Add TaskInterface/ClientInterface/WorkerInterface providers: IronWorker, pThreads
  • Add documentation

Elsewhere...

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages