File Coverage

blib/lib/GraphQL/PubSub.pm
Criterion Covered Total %
statement 67 67 100.0
branch 17 32 53.1
condition 2 4 50.0
subroutine 14 14 100.0
pod 3 3 100.0
total 103 120 85.8


line stmt bran cond sub pod time code
1             package GraphQL::PubSub;
2              
3 18     18   2557986 use 5.014;
  18         136  
4 18     18   121 use strict;
  18         48  
  18         486  
5 18     18   91 use warnings;
  18         31  
  18         453  
6 18     18   99 use Moo;
  18         34  
  18         103  
7 18     18   12730 use GraphQL::Debug qw(_debug);
  18         46  
  18         997  
8 18     18   7871 use Types::TypeTiny -all;
  18         53070  
  18         84  
9 18     18   89047 use Types::Standard -all;
  18         1197667  
  18         177  
10 18     18   869525 use GraphQL::Type::Library -all;
  18         72  
  18         231  
11 18     18   266494 use GraphQL::MaybeTypeCheck;
  18         50  
  18         70  
12              
13 18     18   53845 use constant DEBUG => $ENV{GRAPHQL_DEBUG};
  18         42  
  18         2241  
14              
15             =head1 NAME
16              
17             GraphQL::PubSub - publish/subscribe
18              
19             =head1 SYNOPSIS
20              
21             use GraphQL::PubSub;
22             my $pubsub = GraphQL::PubSub->new;
23             $pubsub->subscribe('channel1', \&callback);
24             $pubsub->publish('channel1', 1);
25             $pubsub->unsubscribe('channel1', \&callback);
26              
27             =head1 DESCRIPTION
28              
29             Encapsulates the publish/subscribe logic needed by L<GraphQL::Subscription>.
30              
31             =head1 METHODS
32              
33             =head2 subscribe($channel, \&callback[, \&error_callback])
34              
35             Registers the given callback on the given channel.
36              
37             The optional second "error" callback is called as a method on the object
38             when an exception is thrown by the first callback. If not given, the
39             default is for the subscription to be cancelled with L</unsubscribe>. The
40             error callback will be called with values of the channel, the original
41             callback (to enable unsubscribing), the exception thrown, then the values
42             passed to the original callback. Any exceptions will be ignored.
43              
44             =cut
45              
46             has _subscriptions => (is => 'ro', isa => HashRef, default => sub { {} });
47              
48 1 50   1   5 method _default_error_callback(Str $channel, CodeLike $callback, Any $exception, @values) {
  1 50       2  
  1 50       3  
  1 50       4  
  1         12  
  1         11  
  1         9  
49 1         2 eval { $self->unsubscribe($channel, $callback) };
  1         3  
50             }
51              
52 17 50   17 1 3896 method subscribe(Str $channel, CodeLike $callback, Maybe[CodeLike] $error_callback = undef) {
  17 50       43  
  17 50       30  
  17 50       36  
  17 50       52  
  17         254  
  17         250  
  17         140  
53 17   100     168 $self->_subscriptions->{$channel}{$callback} = [
      0        
54             $callback,
55             $error_callback || \&_default_error_callback,
56             ];
57             }
58              
59             =head2 unsubscribe($channel, \&callback)
60              
61             Removes the given callback from the given channel.
62              
63             =cut
64              
65 2 50   2 1 1444 method unsubscribe(Str $channel, CodeLike $callback) {
  2 50       7  
  2 50       4  
  2 50       5  
  2         7  
  2         25  
  2         18  
66 2         12 delete $self->_subscriptions->{$channel}{$callback};
67             }
68              
69             =head2 publish($channel, @values)
70              
71             Calls each callback registered on the given channel, with the given values.
72              
73             =cut
74              
75 21 50   21 1 6772 method publish(Str $channel, @values) {
  21 50       36  
  21         52  
  21         61  
  21         228  
76 21         32 for my $cb (values %{ $self->_subscriptions->{$channel} }) {
  21         92  
77 22         48 my ($normal, $error) = @$cb;
78 22         35 eval { $normal->(@values) };
  22         61  
79 22 100       479 eval { $self->$error($channel, $normal, $@, @values) } if $@;
  2         8  
80             }
81             }
82              
83             __PACKAGE__->meta->make_immutable();
84              
85             1;