The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Net::Curl::Promiser - A Promise interface for Net::Curl::Multi

DESCRIPTION

This module wraps Net::Curl::Multi to facilitate asynchronous HTTP requests with Promise objects.

Net::Curl::Promiser itself is a base class; you’ll need to provide an interface to whatever event loop you use. See "SUBCLASS INTERFACE" below.

This distribution provides the following as both demonstrations and portable implementations:

(See the distribution’s /examples directory for one based on Linux’s epoll.)

PROMISE IMPLEMENTATION

This class’s default Promise implementation is Promise::ES6. You can use a different one by overriding the PROMISE_CLASS() method in a subclass, as long as the substitute class’s new() method works the same way as Promise::ES6’s (which itself follows the ECMAScript standard).

METHODS

CLASS->new(@ARGS)

Instantiates this class. This creates an underlying Net::Curl::Multi object and calls the subclass’s _INIT() method at the end, passing a reference to @ARGS.

promise($EASY) = OBJ->add_handle( $EASY )

A passthrough to the underlying Net::Curl::Multi object’s method of the same name, but the return is given as a Promise object.

That promise resolves with the passed-in $EASY object. It rejects with either the error given to fail_handle() or the error that Net::Curl::Multi object’s info_read() returns.

IMPORTANT: As with libcurl itself, HTTP-level failures (e.g., 4xx and 5xx responses) are NOT considered failures at this level.

$obj = OBJ->fail_handle( $EASY, $REASON )

Prematurely fails $EASY. The given $REASON will be the associated Promise object’s rejection value.

$num = OBJ->get_timeout()

Returns the underlying Net::Curl::Multi object’s timeout() value, with a suitable (positive) default substituted if that value is less than 0.

(NB: This value is in milliseconds.)

This may not suit your needs; if you wish/need, you can handle timeouts via the CURLMOPT_TIMERFUNCTION callback instead.

This should only be called (if it’s called at all) from event loop logic.

$obj = OBJ->process( @ARGS )

Tell the underlying Net::Curl::Multi object which socket events have happened.

If, in fact, no events have happened, then this calls socket_action(CURL_SOCKET_TIMEOUT) on the Net::Curl::Multi object (similar to time_out()).

Finally, this reaps whatever pending HTTP responses may be ready and resolves or rejects the corresponding Promise objects.

This should only be called from event loop logic.

Returns OBJ.

$is_active = OBJ->time_out();

Tell the underlying Net::Curl::Multi object that a timeout happened, and reap whatever pending HTTP responses may be ready.

Calls socket_action(CURL_SOCKET_TIMEOUT) on the underlying Net::Curl::Multi object. The return is the same as that operation returns.

Since process() can also do the work of this function, a call to this function is just an optimization.

This should only be called from event loop logic.

$obj = OBJ->setopt( … )

A passthrough to the underlying Net::Curl::Multi object’s method of the same name. Returns OBJ to facilitate chaining.

IMPORTANT: Don’t set CURLMOPT_SOCKETFUNCTION or CURLMOPT_SOCKETDATA. OBJ needs to set those internally.

$obj = OBJ->handles( … )

A passthrough to the underlying Net::Curl::Multi object’s method of the same name.

SUBCLASS INTERFACE

To use Net::Curl::Promiser, you’ll need a subclass that defines the following methods:

  • _INIT(\@ARGS): Called at the end of new(). Receives a reference to the arguments given to new().

  • _SET_POLL_IN($FD): Tells the event loop that the given file descriptor is ready to read.

  • _SET_POLL_OUT($FD): Like _SET_POLL_IN() but for a write event.

  • _SET_POLL_INOUT($FD): Like _SET_POLL_IN() but registers a read and write event simultaneously.

  • _STOP_POLL($FD): Tells the event loop that the given file descriptor is finished.

  • _GET_FD_ACTION(\@ARGS): Receives a reference to the arguments given to process() and returns a reference to a hash of ( $fd => $event_mask ). $event_mask is the sum of Net::Curl::Multi::CURL_CSELECT_IN() and/or Net::Curl::Multi::CURL_CSELECT_OUT(), depending on which events are available.

EXAMPLES

See the distribution’s /examples directory.

SEE ALSO

If you use AnyEvent, then AnyEvent::XSPromises with AnyEvent::YACurl may be a nicer fit for you.

REPOSITORY

https://github.com/FGasper/p5-Net-Curl-Promiser

LICENSE & COPYRIGHT

Copyright 2019 Gasper Software Consulting.

This library is licensed under the same terms as Perl itself.