Search in sources :

Example 6 with StateMachine

use of org.neo4j.cluster.statemachine.StateMachine in project neo4j by neo4j.

the class StateMachinesTest method whenMessageHandlingCausesNewMessagesThenEnsureCorrectOrder.

@Test
public void whenMessageHandlingCausesNewMessagesThenEnsureCorrectOrder() throws Exception {
    // Given
    StateMachines stateMachines = new StateMachines(NullLogProvider.getInstance(), mock(StateMachines.Monitor.class), mock(MessageSource.class), Mockito.mock(MessageSender.class), Mockito.mock(Timeouts.class), Mockito.mock(DelayedDirectExecutor.class), new Executor() {

        @Override
        public void execute(Runnable command) {
            command.run();
        }
    }, mock(InstanceId.class));
    ArrayList<TestMessage> handleOrder = new ArrayList<>();
    StateMachine stateMachine = new StateMachine(handleOrder, TestMessage.class, TestState.test, NullLogProvider.getInstance());
    stateMachines.addStateMachine(stateMachine);
    // When
    stateMachines.process(internal(TestMessage.message1));
    // Then
    assertThat(handleOrder.toString(), equalTo("[message1, message2, message4, message5, message3]"));
}
Also used : MessageSender(org.neo4j.cluster.com.message.MessageSender) Timeouts(org.neo4j.cluster.timeout.Timeouts) StateMachine(org.neo4j.cluster.statemachine.StateMachine) ArrayList(java.util.ArrayList) MessageSource(org.neo4j.cluster.com.message.MessageSource) Executor(java.util.concurrent.Executor) Test(org.junit.Test)

Example 7 with StateMachine

use of org.neo4j.cluster.statemachine.StateMachine in project neo4j by neo4j.

the class MultiPaxosServerFactory method constructSupportingInfrastructureFor.

/**
     * Sets up the supporting infrastructure and communication hooks for our state machines. This is here to support
     * an external requirement for assembling protocol servers given an existing set of state machines (used to prove
     * correctness).
     */
public ProtocolServer constructSupportingInfrastructureFor(InstanceId me, MessageSource input, MessageSender output, DelayedDirectExecutor executor, Timeouts timeouts, Executor stateMachineExecutor, final MultiPaxosContext context, StateMachine[] machines) {
    StateMachines stateMachines = new StateMachines(logging, stateMachinesMonitor, input, output, timeouts, executor, stateMachineExecutor, me);
    for (StateMachine machine : machines) {
        stateMachines.addStateMachine(machine);
    }
    final ProtocolServer server = new ProtocolServer(me, stateMachines, logging);
    server.addBindingListener(new BindingListener() {

        @Override
        public void listeningAt(URI me) {
            context.getClusterContext().setBoundAt(me);
        }
    });
    stateMachines.addMessageProcessor(new HeartbeatRefreshProcessor(stateMachines.getOutgoing(), context.getClusterContext()));
    input.addMessageProcessor(new HeartbeatIAmAliveProcessor(stateMachines.getOutgoing(), context.getClusterContext()));
    Cluster cluster = server.newClient(Cluster.class);
    cluster.addClusterListener(new HeartbeatJoinListener(stateMachines.getOutgoing()));
    cluster.addClusterListener(new HeartbeatLeftListener(context.getHeartbeatContext(), logging));
    context.getHeartbeatContext().addHeartbeatListener(new HeartbeatReelectionListener(server.newClient(Election.class), logging));
    context.getClusterContext().addClusterListener(new ClusterLeaveReelectionListener(server.newClient(Election.class), logging));
    StateMachineRules rules = new StateMachineRules(stateMachines.getOutgoing()).rule(ClusterState.start, ClusterMessage.create, ClusterState.entered, internal(AtomicBroadcastMessage.entered), internal(ProposerMessage.join), internal(AcceptorMessage.join), internal(LearnerMessage.join), internal(HeartbeatMessage.join), internal(ElectionMessage.created), internal(SnapshotMessage.join)).rule(ClusterState.discovery, ClusterMessage.configurationResponse, ClusterState.joining, internal(AcceptorMessage.join), internal(LearnerMessage.join), internal(AtomicBroadcastMessage.join)).rule(ClusterState.discovery, ClusterMessage.configurationResponse, ClusterState.entered, internal(AtomicBroadcastMessage.entered), internal(ProposerMessage.join), internal(AcceptorMessage.join), internal(LearnerMessage.join), internal(HeartbeatMessage.join), internal(ElectionMessage.join), internal(SnapshotMessage.join)).rule(ClusterState.joining, ClusterMessage.configurationChanged, ClusterState.entered, internal(AtomicBroadcastMessage.entered), internal(ProposerMessage.join), internal(AcceptorMessage.join), internal(LearnerMessage.join), internal(HeartbeatMessage.join), internal(ElectionMessage.join), internal(SnapshotMessage.join)).rule(ClusterState.joining, ClusterMessage.joinFailure, ClusterState.start, internal(AtomicBroadcastMessage.leave), internal(AcceptorMessage.leave), internal(LearnerMessage.leave), internal(ProposerMessage.leave)).rule(ClusterState.entered, ClusterMessage.leave, ClusterState.start, internal(AtomicBroadcastMessage.leave), internal(AcceptorMessage.leave), internal(LearnerMessage.leave), internal(HeartbeatMessage.leave), internal(SnapshotMessage.leave), internal(ElectionMessage.leave), internal(ProposerMessage.leave)).rule(ClusterState.entered, ClusterMessage.leave, ClusterState.start, internal(AtomicBroadcastMessage.leave), internal(AcceptorMessage.leave), internal(LearnerMessage.leave), internal(HeartbeatMessage.leave), internal(ElectionMessage.leave), internal(SnapshotMessage.leave), internal(ProposerMessage.leave)).rule(ClusterState.leaving, ClusterMessage.configurationChanged, ClusterState.start, internal(AtomicBroadcastMessage.leave), internal(AcceptorMessage.leave), internal(LearnerMessage.leave), internal(HeartbeatMessage.leave), internal(ElectionMessage.leave), internal(SnapshotMessage.leave), internal(ProposerMessage.leave)).rule(ClusterState.leaving, ClusterMessage.leaveTimedout, ClusterState.start, internal(AtomicBroadcastMessage.leave), internal(AcceptorMessage.leave), internal(LearnerMessage.leave), internal(HeartbeatMessage.leave), internal(ElectionMessage.leave), internal(SnapshotMessage.leave), internal(ProposerMessage.leave));
    stateMachines.addStateTransitionListener(rules);
    return server;
}
Also used : ClusterLeaveReelectionListener(org.neo4j.cluster.protocol.election.ClusterLeaveReelectionListener) HeartbeatReelectionListener(org.neo4j.cluster.protocol.election.HeartbeatReelectionListener) StateMachine(org.neo4j.cluster.statemachine.StateMachine) StateMachineRules(org.neo4j.cluster.statemachine.StateMachineRules) Cluster(org.neo4j.cluster.protocol.cluster.Cluster) URI(java.net.URI) HeartbeatIAmAliveProcessor(org.neo4j.cluster.protocol.heartbeat.HeartbeatIAmAliveProcessor) HeartbeatRefreshProcessor(org.neo4j.cluster.protocol.heartbeat.HeartbeatRefreshProcessor) HeartbeatJoinListener(org.neo4j.cluster.protocol.heartbeat.HeartbeatJoinListener) HeartbeatLeftListener(org.neo4j.cluster.protocol.heartbeat.HeartbeatLeftListener)

Example 8 with StateMachine

use of org.neo4j.cluster.statemachine.StateMachine in project neo4j by neo4j.

the class ClusterInstance method snapshotStateMachine.

private StateMachine snapshotStateMachine(LogProvider logProvider, MultiPaxosContext snapshotCtx, StateMachine stateMachine) {
    // This is done this way because all the state machines are sharing one piece of global state
    // (MultiPaxosContext), which is snapshotted as one coherent component. This means the state machines
    // cannot snapshot themselves, an external service needs to snapshot the full shared state and then create
    // new state machines sharing that state.
    Object ctx;
    Class<? extends MessageType> msgType = stateMachine.getMessageType();
    if (msgType == AtomicBroadcastMessage.class) {
        ctx = snapshotCtx.getAtomicBroadcastContext();
    } else if (msgType == AcceptorMessage.class) {
        ctx = snapshotCtx.getAcceptorContext();
    } else if (msgType == ProposerMessage.class) {
        ctx = snapshotCtx.getProposerContext();
    } else if (msgType == LearnerMessage.class) {
        ctx = snapshotCtx.getLearnerContext();
    } else if (msgType == HeartbeatMessage.class) {
        ctx = snapshotCtx.getHeartbeatContext();
    } else if (msgType == ElectionMessage.class) {
        ctx = snapshotCtx.getElectionContext();
    } else if (msgType == SnapshotMessage.class) {
        ctx = new SnapshotContext(snapshotCtx.getClusterContext(), snapshotCtx.getLearnerContext());
    } else if (msgType == ClusterMessage.class) {
        ctx = snapshotCtx.getClusterContext();
    } else {
        throw new IllegalArgumentException("I don't know how to snapshot this state machine: " + stateMachine);
    }
    return new StateMachine(ctx, stateMachine.getMessageType(), stateMachine.getState(), logProvider);
}
Also used : ElectionMessage(org.neo4j.cluster.protocol.election.ElectionMessage) StateMachine(org.neo4j.cluster.statemachine.StateMachine) AcceptorMessage(org.neo4j.cluster.protocol.atomicbroadcast.multipaxos.AcceptorMessage) ClusterMessage(org.neo4j.cluster.protocol.cluster.ClusterMessage) LearnerMessage(org.neo4j.cluster.protocol.atomicbroadcast.multipaxos.LearnerMessage) SnapshotContext(org.neo4j.cluster.protocol.snapshot.SnapshotContext)

Aggregations

StateMachine (org.neo4j.cluster.statemachine.StateMachine)8 Executor (java.util.concurrent.Executor)3 Test (org.junit.Test)3 MessageSender (org.neo4j.cluster.com.message.MessageSender)3 MessageSource (org.neo4j.cluster.com.message.MessageSource)3 Timeouts (org.neo4j.cluster.timeout.Timeouts)3 ArrayList (java.util.ArrayList)2 DelayedDirectExecutor (org.neo4j.cluster.DelayedDirectExecutor)2 StateMachines (org.neo4j.cluster.StateMachines)2 Message (org.neo4j.cluster.com.message.Message)2 LearnerMessage (org.neo4j.cluster.protocol.atomicbroadcast.multipaxos.LearnerMessage)2 MultiPaxosContext (org.neo4j.cluster.protocol.atomicbroadcast.multipaxos.context.MultiPaxosContext)2 URI (java.net.URI)1 Collection (java.util.Collection)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 Mockito.doAnswer (org.mockito.Mockito.doAnswer)1 InvocationOnMock (org.mockito.invocation.InvocationOnMock)1 Answer (org.mockito.stubbing.Answer)1 InstanceId (org.neo4j.cluster.InstanceId)1