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   2486168 use 5.014;
  18         119  
4 18     18   102 use strict;
  18         33  
  18         472  
5 18     18   127 use warnings;
  18         27  
  18         469  
6 18     18   106 use Moo;
  18         33  
  18         98  
7 18     18   12463 use GraphQL::Debug qw(_debug);
  18         42  
  18         1011  
8 18     18   7587 use Types::TypeTiny -all;
  18         51935  
  18         77  
9 18     18   87610 use Types::Standard -all;
  18         1177476  
  18         198  
10 18     18   805286 use GraphQL::Type::Library -all;
  18         73  
  18         234  
11 18     18   251596 use GraphQL::MaybeTypeCheck;
  18         58  
  18         113  
12              
13 18     18   53716 use constant DEBUG => $ENV{GRAPHQL_DEBUG};
  18         44  
  18         2219  
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       3  
  1 50       5  
  1 50       5  
  1         11  
  1         10  
  1         9  
49 1         3 eval { $self->unsubscribe($channel, $callback) };
  1         3  
50             }
51              
52 17 50   17 1 3224 method subscribe(Str $channel, CodeLike $callback, Maybe[CodeLike] $error_callback = undef) {
  17 50       35  
  17 50       29  
  17 50       41  
  17 50       57  
  17         236  
  17         138  
  17         122  
53 17   100     150 $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 1322 method unsubscribe(Str $channel, CodeLike $callback) {
  2 50       6  
  2 50       5  
  2 50       4  
  2         5  
  2         21  
  2         14  
66 2         10 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 5050 method publish(Str $channel, @values) {
  21 50       30  
  21         43  
  21         48  
  21         179  
76 21         23 for my $cb (values %{ $self->_subscriptions->{$channel} }) {
  21         74  
77 22         42 my ($normal, $error) = @$cb;
78 22         28 eval { $normal->(@values) };
  22         47  
79 22 100       346 eval { $self->$error($channel, $normal, $@, @values) } if $@;
  2         8  
80             }
81             }
82              
83             __PACKAGE__->meta->make_immutable();
84              
85             1;