Skip to content

Commit

Permalink
Separated HighAvailabilityMembers into HighAvailabilitySlaves / Members
Browse files Browse the repository at this point in the history
and introduced abstractions along the way to be able to write mocked
tests.
  • Loading branch information
tinwelint committed Nov 19, 2012
1 parent 104c941 commit 2ccaa35
Show file tree
Hide file tree
Showing 35 changed files with 1,975 additions and 490 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ public class ClusterDatabaseInfo extends ClusterMemberInfo
private final long lastCommittedTxId;
private final long lastUpdateTime;

public ClusterDatabaseInfo( String instanceId, boolean available, String haRole, String[] clusterRoles, String[] uris,
long lastCommittedTxId, long lastUpdateTime )
public ClusterDatabaseInfo( ClusterMemberInfo memberInfo, long lastCommittedTxId, long lastUpdateTime )
{
super( instanceId, available, haRole, clusterRoles, uris );
super( memberInfo.getInstanceId(), memberInfo.isAvailable(), memberInfo.isAlive(), memberInfo.getHaRole(),
memberInfo.getClusterRoles(), memberInfo.getUris() );
this.lastCommittedTxId = lastCommittedTxId;
this.lastUpdateTime = lastUpdateTime;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,18 @@ public class ClusterMemberInfo implements Serializable
private static final long serialVersionUID = 1L;
private final String instanceId;
private final boolean available;
private final boolean alive;
private final String haRole;
private final String[] clusterRoles;
private final String[] uris;

@ConstructorProperties( { "instanceId", "available", "haRole", "clusterRoles", "uris" } )
public ClusterMemberInfo( String instanceId, boolean available, String haRole, String[] clusterRoles, String[] uris )
@ConstructorProperties( { "instanceId", "available", "alive", "haRole", "clusterRoles", "uris" } )
public ClusterMemberInfo( String instanceId, boolean available, boolean alive, String haRole,
String[] clusterRoles, String[] uris )
{
this.instanceId = instanceId;
this.available = available;
this.alive = alive;
this.haRole = haRole;
this.clusterRoles = clusterRoles;
this.uris = uris;
Expand All @@ -62,6 +65,11 @@ public boolean isAvailable()
return available;
}

public boolean isAlive()
{
return alive;
}

public String getHaRole()
{
return haRole;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public interface HighAvailability
@Description( "Whether this instance is available or not" )
boolean isAvailable();

@Description( "Whether this instance is alive or not" )
boolean isAlive();

@Description( "The role this instance has in the cluster" )
String getRole();

Expand Down
27 changes: 27 additions & 0 deletions enterprise/cluster/src/main/java/org/neo4j/cluster/Binding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* 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;

public interface Binding
{
void addBindingListener( BindingListener listener );

void removeBindingListener( BindingListener listener );
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* 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;

import org.neo4j.cluster.protocol.cluster.ClusterListener;
import org.neo4j.cluster.protocol.heartbeat.Heartbeat;

/**
* Bundles up different ways of listening in on events going on
* in a cluster.
*
* {@link Binding} for notifications about which URI is used
* for sending events of the network.
* {@link Heartbeat} for notifications about failed/alive members.
* {@link #addClusterListener(ClusterListener)}, {@link #removeClusterListener(ClusterListener)
* for getting notified about cluster membership events.
*
* @author Mattias Persson
*/
public interface ClusterMonitor extends Binding, Heartbeat
{
void addClusterListener( ClusterListener listener);

void removeClusterListener( ClusterListener listener);
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.concurrent.TimeUnit;

import org.neo4j.cluster.BindingListener;
import org.neo4j.cluster.ClusterMonitor;
import org.neo4j.cluster.ClusterSettings;
import org.neo4j.cluster.ConnectedStateMachines;
import org.neo4j.cluster.MultiPaxosServerFactory;
Expand Down Expand Up @@ -56,7 +57,7 @@
import org.neo4j.kernel.lifecycle.LifecycleAdapter;
import org.neo4j.kernel.logging.Logging;

public class ClusterClient extends LifecycleAdapter implements Cluster, AtomicBroadcast, Heartbeat
public class ClusterClient extends LifecycleAdapter implements ClusterMonitor, Cluster, AtomicBroadcast
{
private final LifeSupport life = new LifeSupport();
private final Cluster cluster;
Expand Down Expand Up @@ -175,8 +176,8 @@ public String getAddress()
}
}, StringLogger.SYSTEM );

server = life.add( protocolServerFactory.newProtocolServer( timeoutStrategy, networkNodeTCP, networkNodeTCP,
acceptorInstanceStore, electionCredentialsProvider ) );
server = protocolServerFactory.newProtocolServer( timeoutStrategy, networkNodeTCP, networkNodeTCP,
acceptorInstanceStore, electionCredentialsProvider );

networkNodeTCP.addNetworkChannelsListener( new NetworkInstance.NetworkChannelsListener()
{
Expand Down Expand Up @@ -344,10 +345,17 @@ public void removeHeartbeatListener( HeartbeatListener listener )
heartbeat.removeHeartbeatListener( listener );
}

@Override
public void addBindingListener( BindingListener bindingListener )
{
server.addBindingListener( bindingListener );
}

@Override
public void removeBindingListener( BindingListener listener )
{
server.removeBindingListener( listener );
}

public void dumpDiagnostics( StringBuilder appendTo )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,7 @@ public void setRoles( Map<String, URI> roles )
assert members.contains( uri );
}

this.roles.clear();
this.roles.putAll( roles );
this.roles = new HashMap<String, URI>( roles );
}

public List<URI> getMembers()
Expand Down
2 changes: 1 addition & 1 deletion enterprise/com/src/main/java/org/neo4j/com/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
package org.neo4j.com;

import static org.neo4j.com.Protocol.addLengthFieldPipes;
import static org.neo4j.com.Protocol.assertChunkSizeIsWithinFrameSize;
import static org.neo4j.com.Protocol.readString;
import static org.neo4j.com.Protocol.writeString;
import static org.neo4j.com.Server.assertChunkSizeIsWithinFrameSize;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
*/
package org.neo4j.kernel;

import static org.neo4j.helpers.collection.IteratorUtil.asCollection;

import org.neo4j.kernel.ha.ClusterDatabaseInfoProvider;
import org.neo4j.kernel.ha.HighAvailabilityMembers;
import org.neo4j.kernel.ha.HighAvailabilityMembers.MemberInfo;
import org.neo4j.kernel.ha.HighlyAvailableGraphDatabase;
import org.neo4j.kernel.ha.cluster.member.HighAvailabilityMembers;
import org.neo4j.management.ClusterDatabaseInfo;
import org.neo4j.management.ClusterMemberInfo;

public class HighlyAvailableKernelData extends KernelData
{
Expand Down Expand Up @@ -52,9 +54,9 @@ public GraphDatabaseAPI graphDatabase()
return db;
}

public MemberInfo[] getClusterInfo()
public ClusterMemberInfo[] getClusterInfo()
{
return memberInfo.getMembers();
return asCollection( memberInfo.getMembers() ).toArray( new ClusterMemberInfo[0] );
}

public ClusterDatabaseInfo getMemberInfo()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import org.neo4j.cluster.BindingListener;
import org.neo4j.cluster.client.ClusterClient;
import org.neo4j.kernel.ha.HighAvailabilityMembers.MemberInfo;
import org.neo4j.kernel.ha.cluster.member.HighAvailabilityMembers;
import org.neo4j.management.ClusterDatabaseInfo;
import org.neo4j.management.ClusterMemberInfo;

Expand All @@ -47,13 +47,13 @@ public void listeningAt( URI uri )

public ClusterDatabaseInfo getInfo()
{
for ( MemberInfo member : members.getMembers() )
if ( member.getClusterUri().equals( me ) )
for ( ClusterMemberInfo member : members.getMembers() )
{
if ( member.getInstanceId().equals( me.toString() ) )
{
ClusterMemberInfo info = HighAvailabilityBean.clusterMemberInfo( member );
return new ClusterDatabaseInfo( info.getInstanceId(), info.isAvailable(),
info.getHaRole(), info.getClusterRoles(), info.getUris(), 0, 0 );
return new ClusterDatabaseInfo( member, 0, 0 );
}
}

// TODO return something instead of throwing exception, right?
throw new IllegalStateException( "Couldn't find any information about myself, can't be right" );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* 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.kernel.ha;

import static org.neo4j.kernel.ha.cluster.HighAvailabilityModeSwitcher.getServerId;

import java.net.URI;

import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.impl.nioneo.store.StoreId;
import org.neo4j.kernel.impl.nioneo.xa.NeoStoreXaDataSource;
import org.neo4j.kernel.impl.transaction.DataSourceRegistrationListener;
import org.neo4j.kernel.impl.transaction.XaDataSourceManager;
import org.neo4j.kernel.impl.transaction.xaframework.XaDataSource;
import org.neo4j.kernel.impl.util.StringLogger;

public class DefaultSlaveFactory implements SlaveFactory
{
private StringLogger logger;
private int maxConcurrentChannelsPerSlave;
private int chunkSize;
private StoreId storeId;

public DefaultSlaveFactory( XaDataSourceManager xaDsm, StringLogger logger,
int maxConcurrentChannelsPerSlave, int chunkSize )
{
this.logger = logger;
this.maxConcurrentChannelsPerSlave = maxConcurrentChannelsPerSlave;
this.chunkSize = chunkSize;
xaDsm.addDataSourceRegistrationListener( new StoreIdSettingListener() );
}

@Override
public Slave newSlave( URI uri )
{
return new SlaveClient( getServerId( uri ), uri.getHost(), uri.getPort(), logger, storeId,
maxConcurrentChannelsPerSlave, chunkSize );
}

private class StoreIdSettingListener extends DataSourceRegistrationListener.Adapter
{
@Override
public void registeredDataSource( XaDataSource ds )
{
if ( ds.getName().equals( Config.DEFAULT_DATA_SOURCE_NAME ) )
storeId = ((NeoStoreXaDataSource) ds).getStoreId();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
import org.neo4j.kernel.DefaultIdGeneratorFactory;
import org.neo4j.kernel.IdGeneratorFactory;
import org.neo4j.kernel.IdType;
import org.neo4j.kernel.ha.cluster.HighAvailability;
import org.neo4j.kernel.ha.cluster.HighAvailabilityMemberChangeEvent;
import org.neo4j.kernel.ha.cluster.HighAvailabilityMemberListener;
import org.neo4j.kernel.ha.cluster.HighAvailabilityMemberState;
import org.neo4j.kernel.ha.cluster.HighAvailabilityMemberStateMachine;
import org.neo4j.kernel.impl.nioneo.store.FileSystemAbstraction;
import org.neo4j.kernel.impl.nioneo.store.IdGenerator;
import org.neo4j.kernel.impl.nioneo.store.IdRange;
Expand All @@ -42,10 +42,10 @@ public class HaIdGeneratorFactory implements IdGeneratorFactory
private final IdGeneratorFactory localFactory = new DefaultIdGeneratorFactory();
private final Master master;

public HaIdGeneratorFactory( Master master, HighAvailabilityMemberStateMachine stateHandler )
public HaIdGeneratorFactory( Master master, HighAvailability highAvailability )
{
this.master = master;
stateHandler.addClusterMemberListener( new HaIdGeneratorFactoryClusterMemberListener() );
highAvailability.addHighAvailabilityMemberListener( new HaIdGeneratorFactoryClusterMemberListener() );
}

@Override
Expand Down
Loading

0 comments on commit 2ccaa35

Please sign in to comment.