File Coverage

examples/05-sse-broadcaster/app.pl
Criterion Covered Total %
statement 27 27 100.0
branch 6 10 60.0
condition 1 3 33.3
subroutine 6 6 100.0
pod n/a
total 40 46 86.9


line stmt bran cond sub pod time code
1 1     1   247882 use strict;
  1         3  
  1         72  
2 1     1   8 use warnings;
  1         2  
  1         73  
3 1     1   7 use Future::AsyncAwait;
  1         5  
  1         14  
4              
5             # Try to load Future::IO for loop-agnostic sleep, fall back to immediate if not available
6             my $HAS_FUTURE_IO = eval { require Future::IO; 1 };
7              
8             sub maybe_sleep {
9 3     3   6 my ($seconds) = @_;
10 3 50       37 return $HAS_FUTURE_IO ? Future::IO->sleep($seconds) : Future->done;
11             }
12              
13 1     1   1 async sub watch_sse_disconnect {
14 1         2 my ($receive) = @_;
15              
16 1         1 while (1) {
17 2         4 my $event = await $receive->();
18 1 50       15 return $event if $event->{type} eq 'sse.disconnect';
19             }
20             }
21              
22 2     2   5 async sub app {
23 2         5 my ($scope, $receive, $send) = @_;
24              
25 2 100       36 die "Unsupported scope type: $scope->{type}" if $scope->{type} ne 'sse';
26              
27 1         6 await $send->({
28             type => 'sse.start',
29             status => 200,
30             headers => [ [ 'content-type', 'text/event-stream' ] ],
31             });
32              
33 1         42 my $disconnect = watch_sse_disconnect($receive);
34 1         38 my @events = (
35             { event => 'tick', data => '1' },
36             { event => 'tick', data => '2' },
37             { event => 'done', data => 'finished' },
38             );
39              
40 1         3 for my $msg (@events) {
41 3 50       150 last if $disconnect->is_ready;
42 3         27 await maybe_sleep(1);
43 3         3004693 await $send->({ type => 'sse.send', %$msg });
44             }
45              
46 1 50 33     70 $disconnect->cancel if $disconnect->can('cancel') && !$disconnect->is_ready;
47             }
48              
49             \&app; # Return coderef when loaded via do