/** * Copyright (c) 2002-2012 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.neo4j.cluster.protocol.atomicbroadcast.multipaxos; import java.net.URI; import java.util.ArrayList; import java.util.List; /** * Record of an individual Paxos instance, from a proposer perspective */ public class PaxosInstance { enum State { empty, p1_pending, p1_ready, p2_pending, closed, delivered } PaxosInstanceStore store; InstanceId id = null; State state = State.empty; long ballot = 0; List<URI> acceptors; List<ProposerMessage.PromiseState> promises = new ArrayList<ProposerMessage.PromiseState>(); List<ProposerMessage.AcceptedState> accepts = new ArrayList<ProposerMessage.AcceptedState>(); Object value_1; long phase1Ballot = 0; Object value_2; boolean clientValue = false; public PaxosInstance( PaxosInstanceStore store, InstanceId instanceId ) { this.store = store; this.id = instanceId; } public boolean isState( State s ) { return state.equals( s ); } public void propose( long ballot, List<URI> acceptors ) { this.state = State.p1_pending; this.acceptors = acceptors; this.ballot = ballot; } public void phase1Timeout( long ballot, List<URI> newAcceptors ) { this.ballot = ballot; promises.clear(); this.acceptors = newAcceptors; } public void promise( ProposerMessage.PromiseState promiseState ) { promises.add( promiseState ); if ( promiseState.getValue() != null && promiseState.getBallot() > phase1Ballot ) { value_1 = promiseState.getValue(); phase1Ballot = promiseState.getBallot(); } } public void ready( Object value, boolean clientValue ) { state = State.p1_ready; promises.clear(); value_1 = null; phase1Ballot = 0; value_2 = value; this.clientValue = clientValue; } public void pending() { state = State.p2_pending; } public void acceptRejected() { state = State.empty; promises.clear(); acceptors = null; phase1Ballot = 0; value_1 = null; value_2 = null; clientValue = false; } public void phase2Timeout( long ballot ) { state = State.p1_pending; this.ballot = ballot; promises.clear(); value_1 = null; phase1Ballot = 0; } public void accepted( ProposerMessage.AcceptedState acceptedState ) { accepts.add( acceptedState ); } public void closed( Object value ) { value_2 = value; state = State.closed; accepts.clear(); acceptors = null; } public void delivered() { state = State.delivered; store.delivered( id ); } public List<URI> getAcceptors() { return acceptors; } @Override public String toString() { return id + ": " + state.name() + " b=" + ballot; } }