Algorithm-Paxos

 view release on metacpan or  search on metacpan

lib/Algorithm/Paxos/Role/Proposer.pm  view on Meta::CPAN

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



( run in 0.644 second using v1.01-cache-2.11-cpan-39bf76dae61 )