File Coverage

blib/lib/Mojo/Promise/Role/Futurify.pm
Criterion Covered Total %
statement 18 18 100.0
branch 2 4 50.0
condition n/a
subroutine 6 6 100.0
pod 1 1 100.0
total 27 29 93.1


line stmt bran cond sub pod time code
1             package Mojo::Promise::Role::Futurify;
2              
3 1     1   1103 use Future::Mojo;
  1         12664  
  1         30  
4 1     1   9 use Scalar::Util;
  1         2  
  1         58  
5 1     1   10 use Role::Tiny;
  1         2  
  1         4  
6              
7             our $VERSION = 'v1.0.0';
8              
9             requires qw(ioloop then);
10              
11             sub futurify {
12 5     5 1 6730 my $self = shift;
13 5         20 my $f = Future::Mojo->new($self->ioloop);
14 5         181 Scalar::Util::weaken(my $weak_f = $f);
15 3 50   3   202744 $self->then(sub { $weak_f->done(@_) if $weak_f; 1 },
  3         143  
16 5 50   2   35 sub { $weak_f->fail(@_) if $weak_f; 1 });
  2         101020  
  2         118  
17 5         287 return $f;
18             }
19              
20             1;
21              
22             =head1 NAME
23              
24             Mojo::Promise::Role::Futurify - Chain a Future from a Mojo::Promise
25              
26             =head1 SYNOPSIS
27              
28             use Mojo::Promise;
29            
30             my $promise = Mojo::Promise->with_roles('+Futurify')->new;
31             my $future = $promise->futurify->on_ready(sub {
32             my $f = shift;
33             say $f->is_done ? 'Done' : 'Failed';
34             });
35             $promise->ioloop->timer(5 => sub { $promise->resolve });
36             $future->await;
37            
38             use Mojo::UserAgent;
39             my $ua = Mojo::UserAgent->new;
40            
41             # complicated way of doing $ua->get('https://example.com')
42             my $tx = $ua->get_p('https://example.com')->with_roles('+Futurify')->futurify->get;
43            
44             # using Future composition methods
45             my @futures;
46             foreach my $url (@urls) {
47             push @futures, $ua->get_p($url)->with_roles('+Futurify')->futurify;
48             }
49            
50             use Future;
51             Future->wait_all(@futures)->then(sub {
52             foreach my $f (@_) {
53             if ($f->is_done) {
54             my $tx = $f->get;
55             } elsif ($f->is_failed) {
56             my $err = $f->failure;
57             }
58             }
59             })->await;
60            
61             # using Future::Utils in a Mojolicious application
62             use Mojolicious::Lite;
63             use Future::Utils 'fmap_concat';
64             my $ua = Mojo::UserAgent->new;
65            
66             get '/foo' => sub {
67             my $c = shift;
68             my $count = $c->param('count') // 50;
69            
70             my $f = fmap_concat {
71             $ua->get_p('https://example.com')->with_roles('+Futurify')->futurify;
72             } foreach => [1..$count], concurrent => 10;
73            
74             my $tx = $c->render_later->tx;
75             $f->on_done(sub {
76             my @txs = @_;
77             $c->render(json => [titles => map { $_->res->dom->at('title')->text } @txs]);
78             })->on_fail(sub {
79             $c->reply->exception(@_);
80             })->on_ready(sub { undef $tx })->retain;
81             };
82            
83             app->start;
84              
85             =head1 DESCRIPTION
86              
87             L provides an interface to chain L
88             objects from L objects.
89              
90             =head1 METHODS
91              
92             L composes the following methods.
93              
94             =head2 futurify
95              
96             my $future = $promise->futurify;
97              
98             Returns a L object that will become ready with success or failure
99             when the L resolves or rejects.
100              
101             =head1 BUGS
102              
103             Report any issues on the public bugtracker.
104              
105             =head1 AUTHOR
106              
107             Dan Book
108              
109             =head1 COPYRIGHT AND LICENSE
110              
111             This software is Copyright (c) 2017 by Dan Book.
112              
113             This is free software, licensed under:
114              
115             The Artistic License 2.0 (GPL Compatible)
116              
117             =head1 SEE ALSO
118              
119             L, L, L