File Coverage

blib/lib/Dancer2/Core/Response/Delayed.pm
Criterion Covered Total %
statement 15 15 100.0
branch 2 2 100.0
condition n/a
subroutine 4 4 100.0
pod 1 1 100.0
total 22 22 100.0


line stmt bran cond sub pod time code
1             package Dancer2::Core::Response::Delayed;
2             # ABSTRACT: Delayed responses
3             $Dancer2::Core::Response::Delayed::VERSION = '0.400001';
4 138     138   1667 use Moo;
  138         321  
  138         809  
5 138     138   45666 use Dancer2::Core::Types qw<CodeRef InstanceOf>;
  138         365  
  138         1672  
6              
7             has request => (
8             is => 'ro',
9             isa => InstanceOf['Dancer2::Core::Request'],
10             required => 1,
11             );
12              
13             has response => (
14             is => 'ro',
15             isa => InstanceOf['Dancer2::Core::Response'],
16             required => 1,
17             handles => [qw/status headers push_header/],
18             );
19              
20             has cb => (
21             is => 'ro',
22             isa => CodeRef,
23             required => 1,
24             );
25              
26             has error_cb => (
27             is => 'ro',
28             isa => CodeRef,
29             predicate => '_has_error_cb',
30             );
31              
32             sub is_halted() {0}
33             sub has_passed() {0}
34              
35             sub to_psgi {
36 17     17 1 6510 my $self = shift;
37              
38             return sub {
39 17     17   1497 my $responder = shift;
40              
41 17         63 local $Dancer2::Core::Route::REQUEST = $self->request;
42 17         55 local $Dancer2::Core::Route::RESPONSE = $self->response;
43 17         38 local $Dancer2::Core::Route::RESPONDER = $responder;
44 17         38 local $Dancer2::Core::Route::WRITER;
45              
46 17 100       92 local $Dancer2::Core::Route::ERROR_HANDLER =
47             $self->_has_error_cb ? $self->error_cb : undef;
48              
49 17         92 $self->cb->();
50 17         116 };
51             }
52              
53             1;
54              
55             __END__
56              
57             =pod
58              
59             =encoding UTF-8
60              
61             =head1 NAME
62              
63             Dancer2::Core::Response::Delayed - Delayed responses
64              
65             =head1 VERSION
66              
67             version 0.400001
68              
69             =head1 SYNOPSIS
70              
71             my $response = Dancer2::Core::Response::Delayed->new(
72             request => Dancer2::Core::Request->new(...),
73             response => Dancer2::Core::Response->new(...),
74             cb => sub {...},
75              
76             # optional error handling
77             error_cb => sub {
78             my ($error) = @_;
79             ...
80             },
81             );
82              
83             # or in an app
84             get '/' => sub {
85             # delayed response:
86             delayed {
87             # streaming content
88             content "data";
89             content "more data";
90              
91             # close user connection
92             done;
93             } on_error => sub {
94             my ($error) = @_;
95             warning 'Failed to stream to user: ' . request->remote_address;
96             };
97             };
98              
99             =head1 DESCRIPTION
100              
101             This object represents a delayed (asynchronous) response for L<Dancer2>.
102             It can be used via the C<delayed> keyword.
103              
104             It keeps references to a request and a response in order to avoid
105             keeping a reference to the application.
106              
107             =head1 ATTRIBUTES
108              
109             =head2 request
110              
111             Contains a request the delayed response uses.
112              
113             In the context of a web request, this will be the request that existed
114             when the delayed response has been created.
115              
116             =head2 response
117              
118             Contains a response the delayed response uses.
119              
120             In the context of a web request, this will be the response that existed
121             when the delayed response has been created.
122              
123             =head2 cb
124              
125             The code that will be run asynchronously.
126              
127             =head2 error_cb
128              
129             A callback for handling errors. This callback receives the error as its
130             first (and currently only) parameter.
131              
132             =head1 METHODS
133              
134             =head2 is_halted
135              
136             A method indicating whether the response has halted.
137              
138             This is useless in the context of an asynchronous request so it simply
139             returns no.
140              
141             This method is likely going away.
142              
143             =head2 has_passed
144              
145             A method indicating whether the response asked to skip the current
146             response.
147              
148             This is useless in the context of an asynchronous request so it simply
149             returns no.
150              
151             This method is likely going away.
152              
153             =head2 to_psgi
154              
155             Create a PSGI response. The way it works is by returning a proper PSGI
156             response subroutine which localizes the request and response (in case
157             the callback wants to edit them without a reference to them), and then
158             calls the callback.
159              
160             Finally, when the callback is done, it asks the response (whether it
161             was changed or not) to create its own PSGI response (calling C<to_psgi>)
162             and sends that to the callback it receives as a delayed response.
163              
164             =head1 AUTHOR
165              
166             Dancer Core Developers
167              
168             =head1 COPYRIGHT AND LICENSE
169              
170             This software is copyright (c) 2023 by Alexis Sukrieh.
171              
172             This is free software; you can redistribute it and/or modify it under
173             the same terms as the Perl 5 programming language system itself.
174              
175             =cut