package Algorithm::Paxos::Role::Proposer;
{
$Algorithm::Paxos::Role::Proposer::VERSION = '0.001';
}
use 5.10.0;
use Moose::Role;
use namespace::autoclean;
# ABSTRACT: A Proposer role for the Paxos algorithm
use Try::Tiny;
use Algorithm::Paxos::Exception;
has acceptors => (
isa => 'ArrayRef',
writer => '_set_acceptors',
traits => ['Array'],
handles => {
acceptors => 'elements',
acceptor_count => 'count',
}
);
sub is_quorum {
my ( $self, @replies ) = @_;
my @successes = grep {defined} @replies;
return @successes > ( $self->acceptor_count / 2 );
}
sub highest_proposal_id {
my ( $self, @replies ) = @_;
my @successes = grep {defined} @replies;
return ( sort @successes )[0];
}
sub new_proposal_id { state $i++ }
sub prospose {
my ( $self, $value ) = @_;
my $n = $self->new_proposal_id;
my @replies = map {
try { $self->prepare($n) }
catch { warn $_; undef }
} $self->acceptors;
if ( $self->is_quorum(@replies) ) {
my $v = $self->highest_proposal_id(@replies);
$v ||= $value;
$_->accept( $n, $v ) for $self->acceptors;
return $n;
}
throw("Proposal failed to reach quorum");
}
1;
=pod
=head1 NAME
Algorithm::Paxos::Role::Proposer - A Proposer role for the Paxos algorithm
=head1 VERSION
version 0.001
=head1 SYNOPSIS
package MyApp::PaxosBasic;
use Moose;
with qw(Algorithm::Paxos::Role::Proposer);
1;
__END__
=head1 DESCRIPTION
From L<Wikipedia|http://en.wikipedia.org/wiki/Paxos_algorithm>
A Proposer advocates a client request, attempting to convince the
Acceptors to agree on it, and acting as a coordinator to move the protocol
forward when conflicts occur.
=head1 METHODS
=head2 acceptors ( ) : @acceptors
Returns a list of the acceptors.
=head2 acceptor_count ( ) : $count
Returns count of the number of acceptors.
=head2 is_quorum ( @replies ) : $bool
Takes a list of IDs and sees if they meet a quorum.
=head2 highest_proposal_id ( @replies ) : $id
Takes a list of replies and returns the highest proposal id from the list.
=head2 new_proposal_id ( ) : $id
Generates a new proposal id. The default implementation is an increasing
integer (literally C<$i++>).
=head2 prospose ( $value ) : $id
Propose is the main interface between clients and the Paxos cluster/node.
Propose takes a single value (the proposal) and returns the ID that is
assigned to that proposal. If the proposal fails an exception is thrown.
=head1 AUTHOR
Chris Prather <chris@prather.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2012 by Chris Prather.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
__END__