一個多進程容器。 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提供免費的開源許可證。