File Coverage

blib/lib/Mercury/Controller/PushPull.pm
Criterion Covered Total %
statement 25 25 100.0
branch 2 2 100.0
condition n/a
subroutine 6 6 100.0
pod 3 3 100.0
total 36 36 100.0


line stmt bran cond sub pod time code
1             package Mercury::Controller::PushPull;
2             our $VERSION = '0.016';
3             # ABSTRACT: Push/pull message pattern controller
4              
5             #pod =head1 SYNOPSIS
6             #pod
7             #pod # myapp.pl
8             #pod use Mojolicious::Lite;
9             #pod plugin 'Mercury';
10             #pod websocket( '/push/*topic' )
11             #pod ->to( controller => 'PushPull', action => 'push' );
12             #pod websocket( '/pull/*topic' )
13             #pod ->to( controller => 'PushPull', action => 'pull' );
14             #pod
15             #pod =head1 DESCRIPTION
16             #pod
17             #pod This controller enables a Lpull pattern|Mercury::Pattern::PushPull> on
18             #pod a pair of endpoints (L and L.
19             #pod
20             #pod For more information on the push/pull pattern, see L.
21             #pod
22             #pod =head1 SEE ALSO
23             #pod
24             #pod =over
25             #pod
26             #pod =item L
27             #pod
28             #pod =item L
29             #pod
30             #pod =back
31             #pod
32             #pod =cut
33              
34 2     2   5398 use Mojo::Base 'Mojolicious::Controller';
  2         4  
  2         13  
35 2     2   1276 use Mercury::Pattern::PushPull;
  2         6  
  2         11  
36              
37             #pod =method push
38             #pod
39             #pod $app->routes->websocket( '/push/*topic' )
40             #pod ->to( controller => 'PushPull', action => 'push' );
41             #pod
42             #pod Controller action to connect a websocket to a push endpoint. A push client
43             #pod sends messages through the socket. The message will be sent to one of the
44             #pod connected pull clients in a round-robin fashion.
45             #pod
46             #pod This endpoint requires a C in the stash.
47             #pod
48             #pod =cut
49              
50             sub push {
51 2     2 1 1393 my ( $c ) = @_;
52 2         9 my $pattern = $c->_pattern( $c->stash( 'topic' ) );
53 2         9 $pattern->add_pusher( $c->tx );
54 2         9 $c->rendered( 101 );
55             }
56              
57             #pod =method pull
58             #pod
59             #pod $app->routes->websocket( '/pull/*topic' )
60             #pod ->to( controller => 'PushPull', action => 'pull' );
61             #pod
62             #pod Controller action to connect a websocket to a pull endpoint. A pull
63             #pod client will recieve messages from push clients in a round-robin fashion.
64             #pod One message from a pusher will be received by exactly one puller.
65             #pod
66             #pod This endpoint requires a C in the stash.
67             #pod
68             #pod =cut
69              
70             sub pull {
71 6     6 1 4557 my ( $c ) = @_;
72 6         22 my $pattern = $c->_pattern( $c->stash( 'topic' ) );
73 6         32 $pattern->add_puller( $c->tx );
74 6         25 $c->rendered( 101 );
75             }
76              
77             #pod =method post
78             #pod
79             #pod Post a new message to the given topic without subscribing or
80             #pod establishing a WebSocket connection. This allows new messages to be
81             #pod easily pushed by any HTTP client.
82             #pod
83             #pod =cut
84              
85             sub post {
86 1     1 1 1246 my ( $c ) = @_;
87 1         3 my $topic = $c->stash( 'topic' );
88 1         13 my $pattern = $c->_pattern( $topic );
89 1         31 $pattern->send_message( $c->req->body );
90 1         12 $c->render(
91             status => 200,
92             text => '',
93             );
94             }
95              
96             #=method _pattern
97             #
98             # my $pattern = $c->_pattern( $topic );
99             #
100             # Get or create the L object for the given
101             # topic.
102             #
103             #=cut
104              
105             sub _pattern {
106 9     9   95 my ( $c, $topic ) = @_;
107 9         58 my $pattern = $c->mercury->pattern( PushPull => $topic );
108 9 100       69 if ( !$pattern ) {
109 3         17 $pattern = Mercury::Pattern::PushPull->new;
110 3         21 $c->mercury->pattern( PushPull => $topic => $pattern );
111             }
112 9         24 return $pattern;
113             }
114              
115             1;
116              
117             __END__