Pustaka ini menyediakan pembungkus kecil dan mudah untuk ekstensi PCNTL PHP. Ini memungkinkan berjalannya berbagai proses secara paralel, dengan API yang mudah digunakan.
Kami menginvestasikan banyak sumber daya untuk menciptakan paket sumber terbuka terbaik di kelasnya. Anda dapat mendukung kami dengan membeli salah satu produk berbayar kami.
Kami sangat menghargai Anda mengirimi kami kartu pos dari kota asal Anda, yang menyebutkan paket kami mana yang Anda gunakan. Anda akan menemukan alamat kami di halaman kontak kami. Kami mempublikasikan semua kartu pos yang diterima di dinding kartu pos virtual kami.
Anda dapat menginstal paket melalui composer:
composer require spatie/async
use Spatie Async Pool ;
$ pool = Pool:: create ();
foreach ( $ things as $ thing ) {
$ pool -> add ( function () use ( $ thing ) {
/ / Do a thing
})-> then ( function ( $ output ) {
/ / Handle success
})-> catch ( function ( Throwable $ exception ) {
/ / Handle exception
});
}
$ pool -> wait ();
Saat membuat proses asinkron, Anda akan mendapatkan instance ParallelProcess
yang dikembalikan. Anda dapat menambahkan event hooks berikut pada suatu proses.
$ pool
-> add ( function () {
/ / ...
})
-> then ( function ( $ output ) {
/ / On success , `$output` is returned by the process or callable you passed to the queue .
})
-> catch ( function ( $ exception ) {
/ / When an exception is thrown from within a process , it 's caught and passed here.
})
-> timeout ( function () {
/ / A process took too long to finish.
})
;
Daripada menggunakan metode pada objek $pool
, Anda juga dapat menggunakan fungsi pembantu async
dan await
.
use Spatie Async Pool ;
$ pool = Pool:: create ();
foreach ( range ( 1 , 5 ) as $ i ) {
$ pool [] = async ( function () {
usleep ( random_int ( 10 , 1000 ));
return 2 ;
})-> then ( function ( int $ output ) {
$ this -> counter += $ output ;
});
}
await ( $ pool );
Jika Exception
atau Error
muncul dari dalam proses anak, maka dapat ditangkap per proses dengan menentukan panggilan balik dalam metode ->catch()
.
$ pool
-> add ( function () {
/ / ...
})
-> catch ( function ( $ exception ) {
/ / Handle the thrown exception for this child process.
})
;
Jika tidak ada penangan kesalahan yang ditambahkan, kesalahan akan terjadi pada proses induk saat memanggil await()
atau $pool->wait()
.
Jika proses turunan tiba-tiba berhenti tanpa melempar Throwable
, keluaran yang ditulis ke stderr
akan dibungkus dan dilemparkan sebagai SpatieAsyncParallelError
dalam proses induk.
Dengan mengetikkan petunjuk fungsi catch
, Anda dapat menyediakan beberapa penangan kesalahan, masing-masing untuk jenis kesalahan individual.
$ pool
-> add ( function () {
throw new MyException ( ' test ' );
})
-> catch ( function ( MyException $ e ) {
/ / Handle `MyException`
})
-> catch ( function ( OtherException $ e ) {
/ / Handle `OtherException`
});
Perhatikan bahwa segera setelah pengecualian ditangani, pengecualian tersebut tidak akan memicu penangan lainnya
$ pool
-> add ( function () {
throw new MyException ( ' test ' );
})
-> catch ( function ( MyException $ e ) {
/ / This one is triggerd when `MyException` is thrown
})
-> catch ( function ( Exception $ e ) {
/ / This one is not triggerd , even though `M yException ` extends `E xception `
});
Jika Anda perlu menghentikan kumpulan lebih awal, karena tugas yang dijalankannya telah diselesaikan oleh salah satu proses turunan, Anda dapat menggunakan metode $pool->stop()
. Ini akan mencegah kumpulan memulai proses tambahan apa pun.
use Spatie Async Pool ;
$ pool = Pool:: create ();
/ / Generate 10 k processes generating random numbers
for ( $ i = 0 ; $ i < 10000 ; $ i ++) {
$ pool -> add ( function () use ( $ i ) {
return rand ( 0 , 100 );
})-> then ( function ( $ output ) use ( $ pool ) {
/ / If one of them randomly picks 100 , end the pool early .
if ( $ output === 100 ) {
$ pool -> stop ();
}
});
}
$ pool -> wait ();
Perhatikan bahwa kumpulan akan dianggap tidak berguna setelah dihentikan, dan kumpulan baru harus dibuat jika diperlukan.
Secara default, kumpulan akan menggunakan php
untuk menjalankan proses turunannya. Anda dapat mengonfigurasi biner lain seperti ini:
Pool:: create ()
-> withBinary ( ' /path/to/php ' );
Selain menggunakan penutupan, Anda juga dapat bekerja dengan Task
. Task
berguna dalam situasi di mana Anda memerlukan lebih banyak pekerjaan penyiapan dalam proses anak. Karena proses anak selalu di-bootstrap dari nol, kemungkinan besar Anda ingin melakukan inisialisasi misalnya. wadah ketergantungan sebelum menjalankan tugas. Kelas Task
membuat hal ini lebih mudah dilakukan.
use Spatie Async Task ;
class MyTask extends Task
{
public function configure ()
{
/ / Setup eg . dependency container , load config , ...
}
public function run ()
{
/ / Do the real work here.
}
}
/ / Add the task to the pool
$ pool -> add ( new MyTask ());
Jika Anda ingin merangkum logika tugas Anda, tetapi tidak ingin membuat objek Task
yang lengkap, Anda juga dapat meneruskan objek yang dapat dipanggil ke Pool
.
class InvokableClass
{
/ / ...
public function __invoke ()
{
/ / ...
}
}
$ pool -> add ( new InvokableClass ( / * ... * / ));
Anda bebas membuat kumpulan sebanyak yang Anda inginkan, setiap kumpulan memiliki antrian proses sendiri yang akan ditanganinya.
Kumpulan dapat dikonfigurasi oleh pengembang:
use Spatie Async Pool ;
$ pool = Pool:: create ()
/ / The maximum amount of processes which can run simultaneously.
-> concurrency ( 20 )
/ / The maximum amount of time a process may take to finish in seconds
/ / ( decimal places are supported for more granular timeouts ) .
-> timeout ( 15 )
/ / Configure which autoloader sub processes should use.
-> autoload ( __DIR__ . ' /../../vendor/autoload.php ' )
/ / Configure how long the loop should sleep before re - checking the process statuses in microseconds .
-> sleepTime ( 50000 )
;
Jika ekstensi yang diperlukan ( pcntl
dan posix
) tidak diinstal pada runtime PHP Anda saat ini, Pool
akan secara otomatis melakukan fallback ke eksekusi tugas yang sinkron.
Kelas Pool
memiliki metode statis isSupported
yang dapat Anda panggil untuk memeriksa apakah platform Anda dapat menjalankan proses asinkron.
Jika Anda menggunakan Task
untuk menjalankan proses, hanya metode run
tugas tersebut yang akan dipanggil saat dijalankan dalam mode sinkron.
Saat menggunakan paket ini, Anda mungkin bertanya-tanya apa yang terjadi di bawah permukaan.
Kami menggunakan komponen symfony/process
untuk membuat dan mengelola proses anak di PHP. Dengan membuat proses anak dengan cepat, kita dapat mengeksekusi skrip PHP secara paralel. Paralelisme ini dapat meningkatkan kinerja secara signifikan ketika menangani beberapa tugas sinkron, yang tidak perlu menunggu satu sama lain. Dengan memberikan tugas-tugas ini proses terpisah untuk dijalankan, sistem operasi yang mendasarinya dapat menjalankannya secara paralel.
Ada peringatan saat memunculkan proses secara dinamis: Anda perlu memastikan bahwa tidak akan ada terlalu banyak proses sekaligus, atau aplikasi mungkin macet. Kelas Pool
yang disediakan oleh paket ini menangani penanganan sebanyak mungkin proses yang Anda inginkan dengan menjadwalkan dan menjalankannya bila memungkinkan.
Itulah bagian yang dilakukan async()
atau $pool->add()
. Sekarang mari kita lihat apa yang dilakukan await()
atau $pool->wait()
.
Ketika beberapa proses muncul, masing-masing proses dapat memiliki waktu penyelesaian yang berbeda. Satu proses mungkin misalnya. harus menunggu panggilan HTTP, sementara yang lain harus memproses data dalam jumlah besar. Terkadang Anda juga memiliki poin dalam kode Anda yang harus menunggu hingga hasil suatu proses dikembalikan.
Inilah sebabnya mengapa kita harus menunggu pada titik waktu tertentu: agar semua proses di kumpulan selesai, sehingga kita dapat yakin bahwa aman untuk melanjutkan tanpa secara tidak sengaja mematikan proses anak yang belum selesai.
Menunggu seluruh proses dilakukan dengan menggunakan while
loop yang akan menunggu hingga semua proses selesai. Penentuan kapan suatu proses selesai dilakukan dengan menggunakan pendengar pada sinyal SIGCHLD
. Sinyal ini dikeluarkan ketika proses anak selesai oleh kernel OS. Pada PHP 7.1, terdapat dukungan yang jauh lebih baik untuk mendengarkan dan menangani sinyal, menjadikan pendekatan ini lebih berperforma daripada misalnya. menggunakan garpu proses atau soket untuk komunikasi. Anda dapat membaca lebih lanjut tentangnya di sini.
Ketika suatu proses selesai, peristiwa suksesnya dipicu, yang dapat Anda kaitkan dengan fungsi ->then()
. Demikian pula, ketika suatu proses gagal atau kehabisan waktu, loop akan memperbarui status proses tersebut dan melanjutkan. Ketika semua proses selesai, perulangan while akan melihat bahwa tidak ada lagi yang perlu ditunggu, dan berhenti. Inilah saatnya proses induk Anda dapat terus dijalankan.
Kami telah menulis postingan blog yang berisi informasi lebih lanjut tentang kasus penggunaan paket ini, serta membuat perbandingan dengan pustaka PHP asinkron lainnya seperti ReactPHP dan Amp: http://stitcher.io/blog/asynchronous-php.
composer test
Silakan lihat CHANGELOG untuk informasi lebih lanjut tentang apa yang berubah baru-baru ini.
Silakan lihat KONTRIBUSI untuk rinciannya.
Jika Anda menemukan bug terkait keamanan, silakan kirim email ke [email protected] alih-alih menggunakan pelacak masalah.
Anda bebas menggunakan paket ini, namun jika paket ini masuk ke lingkungan produksi Anda, kami sangat menghargai Anda mengirimi kami kartu pos dari kota asal Anda, yang menyebutkan paket kami mana yang Anda gunakan.
Alamat kami adalah: Spatie, Kruikstraat 22, 2018 Antwerp, Belgia.
Kami mempublikasikan semua kartu pos yang diterima di situs web perusahaan kami.
Lisensi MIT (MIT). Silakan lihat File Lisensi untuk informasi lebih lanjut.