一个多进程容器。 Snidel使所有PHP开发人员更容易在没有任何扩展的情况下进行并行处理。

请考虑向该项目的作者Akihito Nakano捐款,以表达您的❤️和支持。
赞助商@ackintosh在Github赞助商上
(en)
没有几个人,使用PHP开始他们的编程运营商,然后继续。并行处理,他们不熟悉它,可能是他们的障碍。
否则,那些不得不使用PHP的语言开发的人(例如一种具有较高功能的语言用于并行处理)。 (过去是我。)
为了使并行处理更轻松,本能地使用它们,我开始开发snidel。
当您考虑“如何并行?”时,Snidel可能是您的选择之一。这对我来说是一种荣幸。
(JA)
我认为有些程序员已经开始使用PHP编程,并通过PHP(我)建立了职业生涯。对于这样的人来说,并行处理可能不熟悉它,或者似乎是一个高阈值。
另外,有些人必须在某种情况下不受PHP以外的其他语言(例如,由于各种情况而具有出色机制的语言)进行开发(例如,我以前是这种情况)。
我们已经开始开发Snidel,目的是使使用并行处理更轻松,直观地解决问题。
我希望Snidel可以成为您的选择之一,如果您说:“我想并行运行此过程,我该怎么办?”
$ composer require ackintosh/snidel:~0.11.0

也可能通过建立功能(例如exec )进行并行处理:
initialize_data_required_for_the_slow_jobs ();
exec ( ' php slow_job1.php & ' );
exec ( ' php slow_job2.php & ' );对于以上感到“痛苦”的开发人员,Snidel可以提供相当不错的体验,并会简化其PHP编程。
我们将浏览用法,以显示Snidel如何并行处理您的编程。使用Snidel的经验应解决您的痛苦。让我们开始吧!
<?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.所有参数都是可选的。
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 ,
]);call_user_func_array相同的参数 // multiple arguments
$ snidel -> process ( $ f , [ ' arg1 ' , ' arg2 ' ]);
// global function
$ snidel -> process ( ' myfunction ' );
// instance method
$ snidel -> process ([ $ instance , ' method ' ]); $ 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 ;
}
}Snidel支持使用Logger进行记录,该记录器实现PSR-3:Logger接口。
// 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}
// ... $ snidel -> process ( function ( $ arg1 , $ arg2 ) {
exit ( 1 );
}, [ ' foo ' , ' bar ' ]);
$ snidel -> get ();
var_dump ( $ snidel -> getError ());
// class AckintoshSnidelError#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
// }
// }Snidel取决于Bernard作为队列抽象层。伯纳德(Bernard)是一个多余的PHP库,用于创建背景作业以供以后处理。
默认情况下,Snidel构建了Flatfile驱动程序,但是从种族条件的角度来看,我们建议在生产中使用更可靠的队列。
$ 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 ,
]);有关驾驶员的详细信息,请参阅此处。
这是引入Snidel的文章。谢谢你!
| Snidel | php |
|---|---|
| 0.1〜0.8 | > = 5.3 |
| 0.9〜 | > = 5.6 |
| 0.13 | > = 7.1 |
我们建议您尝试使用Docker,因为Snidel需要需求中显示的一些PHP扩展。
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/phpunitSnidel ©Ackintosh,根据MIT许可证发布。
由Ackintosh撰写和维护
github @ackintosh / twitter @nakano_akihito / blog(ja)
作者关于Snidel(JA)的博客条目:
感谢Jetbrains提供免费的开源许可证。