Day 13 - Waiting For Multiple Futures
Yesterday we took our first look at some actually-asynchronous uses of a Future, by taking a look at Net::Async::HTTP, but so far in this series we haven't actually seen anything that properly makes use of a Future, that could not be done just as easily synchronously.
Now we can take our first look at some code that uses the asynchronous nature of an HTTP user agent to fetch multiple resources concurrently. By using the Future->needs_all constructor we can create multiple futures to fetch individual pages, then combine them together into a single future which we can then wait on by calling get.
my $f = Future->needs_all( GET( "http://my-site-here.com/page1" ), GET( "http://my-site-here.com/page2" ), GET( "http://my-site-here.com/page3" ), ); my @pages = $f->get;
Here we have created three individual futures representing an HTTP page GET, and wrapped them all in a single wrapper future which will complete when all of its components are complete. The get call on this future then returns a list composed of the result of each individual future. Because we know each one only returns the HTTP::Response object itself, we can just get these as a list. If any of the individual HTTP GET futures fails, the overall combined future will fail too. This means we can neatly handle any exceptions that happen.
When using a properly asynchronous HTTP user agent we are now able to perform these multiple GETs concurrently. Each call to GET starts the fetch operation, which can now all complete concurrently eventually returning their results. This is our first real example of futures providing neat concurrency-enabling code.