org.neo4j.cluster.protocol.snapshot.SnapshotState Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ongdb-cluster Show documentation
Show all versions of ongdb-cluster Show documentation
Library implementing Paxos and Heartbeat components required for High Availability Neo4j
The newest version!
/*
* Copyright (c) 2018-2020 "Graph Foundation"
* Graph Foundation, Inc. [https://graphfoundation.org]
*
* Copyright (c) 2002-2018 "Neo4j,"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of ONgDB Enterprise Edition. The included source
* code can be redistributed and/or modified under the terms of the
* GNU AFFERO GENERAL PUBLIC LICENSE Version 3
* (http://www.fsf.org/licensing/licenses/agpl-3.0.html) as found
* in the associated LICENSE.txt file.
*
* 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.
*/
package org.neo4j.cluster.protocol.snapshot;
import org.neo4j.cluster.InstanceId;
import org.neo4j.cluster.com.message.Message;
import org.neo4j.cluster.com.message.MessageHolder;
import org.neo4j.cluster.protocol.cluster.ClusterConfiguration;
import org.neo4j.cluster.statemachine.State;
/**
* State machine for the snapshot API
*/
public enum SnapshotState
implements State
{
start
{
@Override
public SnapshotState handle( SnapshotContext context,
Message message,
MessageHolder outgoing
)
{
switch ( message.getMessageType() )
{
case setSnapshotProvider:
{
SnapshotProvider snapshotProvider = message.getPayload();
context.setSnapshotProvider( snapshotProvider );
break;
}
case refreshSnapshot:
{
if ( context.getClusterContext().getConfiguration().getMembers().size() <= 1 ||
context.getSnapshotProvider() == null )
{
// we are the only instance or there are no snapshots
return start;
}
else
{
InstanceId coordinator = context.getClusterContext().getConfiguration().getElected(
ClusterConfiguration.COORDINATOR );
if ( coordinator != null )
{
// there is a coordinator - ask from that
outgoing.offer( Message.to( SnapshotMessage.sendSnapshot,
context.getClusterContext().getConfiguration().getUriForId(
coordinator ) ) );
return refreshing;
}
else
{
return start;
}
}
}
case join:
{
// go to ready state, if someone needs snapshots they should ask for it explicitly.
return ready;
}
default:
break;
}
return this;
}
},
refreshing
{
@Override
public SnapshotState handle( SnapshotContext context,
Message message,
MessageHolder outgoing
)
{
if ( message.getMessageType() == SnapshotMessage.snapshot )
{
SnapshotMessage.SnapshotState state = message.getPayload();
state.setState( context.getSnapshotProvider(),
context.getClusterContext().getObjectInputStreamFactory() );
return ready;
}
return this;
}
},
ready
{
@Override
public SnapshotState handle( SnapshotContext context,
Message message,
MessageHolder outgoing
)
{
switch ( message.getMessageType() )
{
case refreshSnapshot:
{
if ( context.getClusterContext().getConfiguration().getMembers().size() <= 1 ||
context.getSnapshotProvider() == null )
{
// we are the only instance in the cluster or snapshots are not meaningful
return ready;
}
else
{
InstanceId coordinator = context.getClusterContext().getConfiguration().getElected(
ClusterConfiguration.COORDINATOR );
if ( coordinator != null && !coordinator.equals( context.getClusterContext().getMyId() ) )
{
// coordinator exists, ask for the snapshot
outgoing.offer( Message.to( SnapshotMessage.sendSnapshot,
context.getClusterContext().getConfiguration().getUriForId(
coordinator ) ) );
return refreshing;
}
else
{
// coordinator is unknown, can't do much
return ready;
}
}
}
case sendSnapshot:
{
outgoing.offer( Message.respond( SnapshotMessage.snapshot, message,
new SnapshotMessage.SnapshotState(
context.getLearnerContext().getLastDeliveredInstanceId(),
context.getSnapshotProvider(),
context.getClusterContext().getObjectOutputStreamFactory() ) ) );
break;
}
case leave:
{
return start;
}
default:
break;
}
return this;
}
}
}