All Projects → ackintosh → Snidel

ackintosh / Snidel

Licence: mit
Snidel makes it easier for all PHP developers to work with parallel processing w/o any extensions.

Projects that are alternatives of or similar to Snidel

funboost
pip install funboost,python全功能分布式函数调度框架,。支持python所有类型的并发模式和全球一切知名消息队列中间件,python函数加速器,框架包罗万象,一统编程思维,兼容50% python编程业务场景,适用范围广。只需要一行代码即可分布式执行python一切函数。旧名字是function_scheduling_distributed_framework
Stars: ✭ 351 (+244.12%)
Mutual labels:  multiprocessing, concurrent
Tractor
structured concurrent, Python parallelism
Stars: ✭ 88 (-13.73%)
Mutual labels:  multiprocessing
Fgbase
Ready-send coordination layer on top of goroutines.
Stars: ✭ 45 (-55.88%)
Mutual labels:  concurrent
Archive Password Cracker
设计精良的压缩包密码破解工具,具有自定义字典、导出字典、选择字典等功能。基于Python实现,支持多线程与多进程,不断完善中……
Stars: ✭ 65 (-36.27%)
Mutual labels:  multiprocessing
Recloser
A concurrent circuit breaker implemented with ring buffers
Stars: ✭ 51 (-50%)
Mutual labels:  concurrent
Oh
A new Unix shell.
Stars: ✭ 1,206 (+1082.35%)
Mutual labels:  concurrent
Routine
go routine control, abstraction of the Main and some useful Executors.如果你不会管理Goroutine的话,用它
Stars: ✭ 40 (-60.78%)
Mutual labels:  concurrent
Broadway
Concurrent and multi-stage data ingestion and data processing with Elixir
Stars: ✭ 1,310 (+1184.31%)
Mutual labels:  concurrent
Multitasking
Non-blocking Python methods using decorators
Stars: ✭ 87 (-14.71%)
Mutual labels:  multiprocessing
Dashmap
Blazing fast concurrent HashMap for Rust.
Stars: ✭ 1,128 (+1005.88%)
Mutual labels:  concurrent
Suman
🌇 🌆 🌉 Advanced, user-friendly, language-agnostic, super-high-performance test runner. http://sumanjs.org
Stars: ✭ 57 (-44.12%)
Mutual labels:  concurrent
Spin
a small utility to assist in setting usage modes of laptop-tablet devices
Stars: ✭ 52 (-49.02%)
Mutual labels:  multiprocessing
Schwimmbad
A common interface to processing pools.
Stars: ✭ 82 (-19.61%)
Mutual labels:  multiprocessing
Coala Quickstart
A tool that generates an initial coala config file for you!
Stars: ✭ 47 (-53.92%)
Mutual labels:  multiprocessing
Tutorials
机器学习相关教程
Stars: ✭ 9,616 (+9327.45%)
Mutual labels:  multiprocessing
Elixirbooks
List of Elixir books
Stars: ✭ 1,021 (+900.98%)
Mutual labels:  concurrent
Freelancer
👔 An implementation of on-the-fly defined WebWorkers that are created inline using data URIs, rather than separate physical files — for the benefit of all humanity.
Stars: ✭ 57 (-44.12%)
Mutual labels:  concurrent
Conget
A CLI app for downloading file concurrently.
Stars: ✭ 72 (-29.41%)
Mutual labels:  concurrent
Php Hyper Builtin Server
Reverse proxy for PHP built-in server which supports multiprocessing and TLS/SSL encryption
Stars: ✭ 93 (-8.82%)
Mutual labels:  multiprocessing
Endurox
Enduro/X Middleware Platform for Distributed Transaction Processing
Stars: ✭ 91 (-10.78%)
Mutual labels:  multiprocessing

Snidel

A multi-process container. Snidel makes it easier for all PHP developers to work with parallel processing without any extensions.

Latest Stable Version License Build Status Scrutinizer Code Quality Coverage Status Minimum PHP Version

Please consider donating to this project's author, Akihito Nakano, to show your ❤️ and support.

Sponsor @ackintosh on GitHub Sponsors

What Snidel solves?

(en)

Not a few people, start their programming carrier with PHP, and go on. Parallel processing, they are not familiar with it, and may be a hurdle for them.

Or else, people who limited to develop with a language that is not PHP (e.g. A language that has superior feature for parallel processing). (It's me in past.)

To make parallel processing more easily and instinctively to them to use, I started developing Snidel.

Snidel can be one of your options when you are considering "How to do it parallelly?". It's an honer for me.

(ja)

PHPでプログラミングに入門して、PHPでキャリアを積み重ねているプログラマがある程度いると思います(私がそうです)。そのような方にとって並列処理は馴染みがなかったり、敷居の高さを感じるのではないでしょうか。

或いは諸事情によりPHP以外の言語(例えば、並列処理のための優れた機構を持った言語)を利用する事を制限されている中で開発を進めなければならない状況にある方もいらっしゃるでしょう(以前の私がそうでした)。

そのような方が、手軽に・直感的に並列処理を使って問題解決できることを目的として Snidel の開発をはじめました。

"この処理を並列に実行したいんだけどどうしよう?" といった場合に Snidel がみなさんの選択肢のひとつになれたら幸いです。

Installing Snidel via Composer

$ composer require ackintosh/snidel:~0.11.0

Architecture

Master - Worker Architecture

Benefits

It is also possible parallel processing via build-in functions (e.g. exec):

initialize_data_required_for_the_slow_jobs();

exec('php slow_job1.php &');
exec('php slow_job2.php &');

For the developers who feels "pain" with the above, Snidel can provides pretty good experience and will streamline their PHP programming.

We will walk through usage to show how Snidel melt parallel processing into your programming. The experience using Snidel should resolve your pain. Let's get started!

Usage

Basic Usage

<?php
use Ackintosh\Snidel;

$f = function ($s) {
    sleep(3);
    echo 'echo: ' . $s;
    return 'return: ' . $s;
};

$s = time();
$snidel = new Snidel();
$snidel->process($f, ['foo']);
$snidel->process($f, ['bar']);
$snidel->process($f, ['baz']);

// `Snidel::results()` returns `\Generator`
foreach ($snidel->results() as $r) {
    // string(9) "echo: foo"
    var_dump($r->getOutput());
    // string(11) "return: foo"
    var_dump($r->getReturn());
}

// If you don't need the results, let's use `Snidel::wait()` instead of `Snidel::results()`
// $snidel->wait();

echo (time() - $s) . 'sec elapsed' . PHP_EOL;
// 3sec elapsed.

Constructor parameters

All parameters are optional.

new Snidel([
    'concurrency' => 3,
    // Please refer to `Logging`
    'logger' => $monolog,
    // Please refer to `Using custom queue`
    'driver' => $driver,
    // a polling duration(in seconds) of queueing
    'pollingDuration' => 1,
]);

Same arguments as call_user_func_array

// multiple arguments
$snidel->process($f, ['arg1', 'arg2']);

// global function
$snidel->process('myfunction');

// instance method
$snidel->process([$instance, 'method']);

Tagging the task

$f = function ($arg) {
    return $arg;
};

$snidel->process($f, 'arg-A_tag1', 'tag1');
$snidel->process($f, 'arg-B_tag1', 'tag1');
$snidel->process($f, 'arg_tag2', 'tag2');

foreach ($snidel->results as $r) {
    // `Task::getTag()` returns the tag passed as 3rd parameter of `Snidel::process()`
    switch ($r->getTask()->getTag()) {
        case 'tag1':
            $r->getReturn(); // arg-A_tag1 | arg-B_tag1
            break;
        case 'tag2':
            $r->getReturn(); // arg_tag2
            break;
        default:
            $r->getReturn();
            break;
    }
}

Logging

Snidel supports logging with logger which implements PSR-3: Logger Interface.

// e.g. MonoLog
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;

$monolog = new Logger('sample');
$stream = new StreamHandler('php://stdout', Logger::DEBUG);
$stream->setFormatter(new LineFormatter("%datetime% > %level_name% > %message% %context%\n"));
$monolog->pushHandler($stream);

$snidel = new Snidel(['logger' => $monolog]);
$snidel->process($f);

// 2017-03-22 13:13:43 > DEBUG > forked worker. pid: 60018 {"role":"master","pid":60017}
// 2017-03-22 13:13:43 > DEBUG > forked worker. pid: 60019 {"role":"master","pid":60017}
// 2017-03-22 13:13:43 > DEBUG > has forked. pid: 60018 {"role":"worker","pid":60018}
// 2017-03-22 13:13:43 > DEBUG > has forked. pid: 60019 {"role":"worker","pid":60019}
// 2017-03-22 13:13:44 > DEBUG > ----> started the function. {"role":"worker","pid":60018}
// 2017-03-22 13:13:44 > DEBUG > ----> started the function. {"role":"worker","pid":60019}
// ...

Error informations of children

$snidel->process(function ($arg1, $arg2) {
    exit(1);
}, ['foo', 'bar']);
$snidel->get();

var_dump($snidel->getError());
// class Ackintosh\Snidel\Error#4244 (1) {
// ...
// }

foreach ($snidel->getError() as $pid => $e) {
    var_dump($pid, $e);
}
// int(51813)
// array(5) {
//   'status' =>  int(256)
//   'message' => string(50) "an error has occurred in child process.
//   'callable' => string(9) "*Closure*"
//   'args' =>
//     array(2) {
//       [0] => string(3) "foo"
//       [1] => string(3) "bar"
//     }
//   'return' => NULL
//   }
// }

Using custom queue

Snidel depends on Bernard as a queue abstraction layer. Bernard is a multi-backend PHP library for creating background jobs for later processing.
By default Snidel builds the flatfile driver, but from a race condition perspective, we recommend using a more reliable queue in production.

Amazon SQS
$connection = Aws\Sqs\SqsClient::factory([
    'key'    => 'your-aws-access-key',
    'secret' => 'your-aws-secret-key',
    'region' => 'the-aws-region-you-choose'
]);
$driver = new Bernard\Driver\SqsDriver($connection);

new Snidel([
    'driver' => $driver,
]);

For details on the driver, please see here.

Articles

Here are articles that introducing Snidel. Thank you!

  • [PHP-Дайджест № 134 (24 июня – 8 июля 2018) / Блог компании Zfort Group / Хабр https://habr.com/ru/company/zfort/blog/416543/]

Requirements

Version Guidance

Snidel PHP
0.1 ~ 0.8 >= 5.3
0.9 ~ >= 5.6
0.13 >= 7.1

Docker

We suggest you give it a try with Docker as Snidel requires some php extensions shown in Requirements.

Run unit tests in docker container

curl -Ss https://getcomposer.org/installer | php
docker build -t snidel .
docker run --rm -v ${PWD}:/snidel snidel php composer.phar install
docker run --rm -v ${PWD}:/snidel snidel vendor/bin/phpunit

Author

Snidel © ackintosh, Released under the MIT License.
Authored and maintained by ackintosh

GitHub @ackintosh / Twitter @NAKANO_Akihito / Blog (ja)

Blog entries by author about Snidel (ja):

Acknowledgments

Thanks to JetBrains for supporting us with a Free Open Source License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].