File Coverage

blib/lib/Algorithm/Paxos/Role/Proposer.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Algorithm::Paxos::Role::Proposer;
2             {
3             $Algorithm::Paxos::Role::Proposer::VERSION = '0.001';
4             }
5 1     1   3631 use 5.10.0;
  1         32  
  1         78  
6 1     1   676 use Moose::Role;
  0            
  0            
7             use namespace::autoclean;
8              
9             # ABSTRACT: A Proposer role for the Paxos algorithm
10              
11             use Try::Tiny;
12             use Algorithm::Paxos::Exception;
13              
14             has acceptors => (
15             isa => 'ArrayRef',
16             writer => '_set_acceptors',
17             traits => ['Array'],
18             handles => {
19             acceptors => 'elements',
20             acceptor_count => 'count',
21             }
22             );
23              
24             sub is_quorum {
25             my ( $self, @replies ) = @_;
26             my @successes = grep {defined} @replies;
27             return @successes > ( $self->acceptor_count / 2 );
28             }
29              
30             sub highest_proposal_id {
31             my ( $self, @replies ) = @_;
32             my @successes = grep {defined} @replies;
33             return ( sort @successes )[0];
34             }
35              
36             sub new_proposal_id { state $i++ }
37              
38             sub prospose {
39             my ( $self, $value ) = @_;
40             my $n = $self->new_proposal_id;
41              
42             my @replies = map {
43             try { $self->prepare($n) }
44             catch { warn $_; undef }
45             } $self->acceptors;
46              
47             if ( $self->is_quorum(@replies) ) {
48             my $v = $self->highest_proposal_id(@replies);
49             $v ||= $value;
50             $_->accept( $n, $v ) for $self->acceptors;
51             return $n;
52             }
53             throw("Proposal failed to reach quorum");
54             }
55              
56             1;
57              
58              
59             =pod
60              
61             =head1 NAME
62              
63             Algorithm::Paxos::Role::Proposer - A Proposer role for the Paxos algorithm
64              
65             =head1 VERSION
66              
67             version 0.001
68              
69             =head1 SYNOPSIS
70              
71             package MyApp::PaxosBasic;
72             use Moose;
73            
74             with qw(Algorithm::Paxos::Role::Proposer);
75            
76             1;
77             __END__
78              
79             =head1 DESCRIPTION
80              
81             From L<Wikipedia|http://en.wikipedia.org/wiki/Paxos_algorithm>
82              
83             A Proposer advocates a client request, attempting to convince the
84             Acceptors to agree on it, and acting as a coordinator to move the protocol
85             forward when conflicts occur.
86              
87             =head1 METHODS
88              
89             =head2 acceptors ( ) : @acceptors
90              
91             Returns a list of the acceptors.
92              
93             =head2 acceptor_count ( ) : $count
94              
95             Returns count of the number of acceptors.
96              
97             =head2 is_quorum ( @replies ) : $bool
98              
99             Takes a list of IDs and sees if they meet a quorum.
100              
101             =head2 highest_proposal_id ( @replies ) : $id
102              
103             Takes a list of replies and returns the highest proposal id from the list.
104              
105             =head2 new_proposal_id ( ) : $id
106              
107             Generates a new proposal id. The default implementation is an increasing
108             integer (literally C<$i++>).
109              
110             =head2 prospose ( $value ) : $id
111              
112             Propose is the main interface between clients and the Paxos cluster/node.
113             Propose takes a single value (the proposal) and returns the ID that is
114             assigned to that proposal. If the proposal fails an exception is thrown.
115              
116             =head1 AUTHOR
117              
118             Chris Prather <chris@prather.org>
119              
120             =head1 COPYRIGHT AND LICENSE
121              
122             This software is copyright (c) 2012 by Chris Prather.
123              
124             This is free software; you can redistribute it and/or modify it under
125             the same terms as the Perl 5 programming language system itself.
126              
127             =cut
128              
129              
130             __END__
131