Search code examples
phpmultithreadingamphp

How does amphp work


The docs on their website http://amphp.org/faq is not very clear to me. Things are confusing to me. Is it intended to run as a server ?? or run as CLI ? or run within a web container ( apache, nginx fpm ) ? And php is sync by nature, how could it be async without support from some kind of extension ( like pthread ).

EDIT ---

Potential application of amp : background thread? In a simple use case like, user submits an order, php may talk along time to process the order. So we want to do in using thread (like Java servlet do it all the time) while not making the user waiting. We know it can be done with cron-job or additional-ajax , but it is ugly and we have alot of this async requirement


Solution

  • Amp uses non-blocking I/O to achieve concurrency. PHP has native support for that via http://php.net/stream_set_blocking.

    Amp can be used in CLI applications, but might also be used inside other SAPIs such as within Apache to make multiple concurrent requests to some service. If you want to embed async into an otherwise sync application, you can use Amp\Promise\wait for that:

    $uris = ["https://google.com/", "https://github.com/"];
    $client = new Amp\Artax\BasicClient;
    
    $promises = array_map(function ($uri) use ($client) {
        return $client->request($uri);
    }, $uris)
    
    $responses = Amp\Promise\wait(Amp\Promise\all($promises));
    

    Amp is usually single-threaded. It's only multi-threaded if you use something like amphp/parallel. amphp/parallel can use pthreads or multiple processes to execute multiple blocking things in parallel.

    If you have more specific questions, just edit your question and comment, I'll try to answer them.


    Regarding background processing, yes that's possible with amphp/parallel, but the original process has to stay alive for that. You could probably implement a disown mechanism in amphp/process to keep the process also running if the parent dies, then it also works inside Apache or PHP-FPM.

    But I'd generally recommend a queue for such tasks, because a queue will make it possible to restart failed tasks (in case a worker crashes) and will not result in extremely high load if there are many background jobs, because not all of them will be started right away, but instead be processed in the background when a worker has time.