Search code examples
phpamphp

AmPHP buffer keeps going forever


I've just picked up AmPHP and I'm trying to get the post body from my AmPHP http server, however, it keeps going forever (just never sends back a response to my client).
This is the code I'm currently using:

$resp = \Amp\Promise\wait($request->getBody()->buffer());

I've tested another piece of code that doesn't keep going forever but when I use that piece, I can't get my body outside the function in the onResolve:

$resp = $request->getBody()->buffer()->onResolve(function($error, $value) {
  return $value;
});
return $resp; // returns null

I've also tried this last bit but that also just returns null:

return yield $request->getBody()->buffer();

Edit: Done some more fiddling around, this is my current (still non-functional) code (although a lot has been stripped out for simplicity sake):

// Main loop
Loop::run(function() {
  $webhook = new Webhook();
  $resp = $webhook->execute($request);
  print_r($resp); // null
});

// Webhook
class Webhook {
  public function execute(\Amp\Http\Server\Request $request) {
    $postbody = yield $request->getBody()->buffer();
    return ['success' => true, 'message' => 'Webhook executed successfully', 'data' => $postbody];
  }
}

Solution

  • Update: After the AMPHP v3 release (changelog) the code would look like this:

    use Amp\Http\Server\Request;
    use Amp\Loop;
    
    class Webhook {
        public function execute(Request $request): \Amp\Promise {
            return new \Amp\Promise(function (callable $resolve) use ($request) {
                $postbody = yield $request->getBody()->buffer();
    
                $resolve([ 'success' => true, 'message' => 'Webhook executed successfully', 'data' => $postbody ]);
            });
        }
    }
    
    // Main loop
    Loop::run(function () {
        $webhook = new Webhook();
        $resp = $webhook->execute($request);
        $output = yield $resp;
        print_r($output); // array with post body
    });
    

    Wrap execute method implementation to Amp\call() to return Promise instead of Generator. Then on the main loop yield the result to get the array instead of null.

    // Webhook
    class Webhook {
        public function execute( \Amp\Http\Server\Request $request ) {
            return Amp\call( function () use ( $request ) {
                $postbody = yield $request->getBody()->buffer();
    
                return [ 'success' => true, 'message' => 'Webhook executed successfully', 'data' => $postbody ];
            } );
        }
    }
    
    // Main loop
    Loop::run( function () {
        $webhook = new Webhook();
        $resp    = $webhook->execute( $request );
        $output  = yield $resp;
        print_r( $resp ); // array with post body
    } );