org.neo4j.kernel.ha.com.slave.MasterClientResolver Maven / Gradle / Ivy
/*
* Copyright (c) 2002-2016 "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 .
*/
package org.neo4j.kernel.ha.com.slave;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
import org.neo4j.com.ComException;
import org.neo4j.com.ComExceptionHandler;
import org.neo4j.com.IllegalProtocolVersionException;
import org.neo4j.com.ProtocolVersion;
import org.neo4j.com.monitor.RequestMonitor;
import org.neo4j.com.storecopy.ResponseUnpacker;
import org.neo4j.kernel.ha.MasterClient210;
import org.neo4j.kernel.ha.MasterClient214;
import org.neo4j.kernel.ha.com.master.InvalidEpochException;
import org.neo4j.kernel.impl.store.StoreId;
import org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel;
import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader;
import org.neo4j.kernel.lifecycle.LifeSupport;
import org.neo4j.kernel.monitoring.ByteCounterMonitor;
import org.neo4j.kernel.monitoring.Monitors;
import org.neo4j.logging.Log;
import org.neo4j.logging.LogProvider;
public class MasterClientResolver implements MasterClientFactory, ComExceptionHandler
{
private volatile MasterClientFactory currentFactory;
private final Map protocolToFactoryMapping;
private final Log log;
private final ResponseUnpacker responseUnpacker;
private final InvalidEpochExceptionHandler invalidEpochHandler;
private final Supplier> logEntryReader;
@Override
public MasterClient instantiate( String destinationHostNameOrIp, int destinationPort, String originHostNameOrIp,
Monitors monitors, StoreId storeId, LifeSupport life )
{
if ( currentFactory == null )
{
assignDefaultFactory();
}
MasterClient result = currentFactory.instantiate( destinationHostNameOrIp, destinationPort, originHostNameOrIp,
monitors, storeId, life );
result.setComExceptionHandler( this );
return result;
}
public MasterClientResolver( LogProvider logProvider, ResponseUnpacker responseUnpacker,
InvalidEpochExceptionHandler invalidEpochHandler,
int readTimeout, int lockReadTimeout, int channels, int chunkSize,
Supplier> logEntryReader )
{
this.logEntryReader = logEntryReader;
this.log = logProvider.getLog( getClass() );
this.responseUnpacker = responseUnpacker;
this.invalidEpochHandler = invalidEpochHandler;
protocolToFactoryMapping = new HashMap<>( 2, 1 );
protocolToFactoryMapping.put( MasterClient210.PROTOCOL_VERSION, new F210( logProvider, readTimeout, lockReadTimeout,
channels, chunkSize ) );
protocolToFactoryMapping.put( MasterClient214.PROTOCOL_VERSION, new F214( logProvider, readTimeout, lockReadTimeout,
channels, chunkSize ) );
}
@Override
public void handle( ComException exception )
{
exception.traceComException( log, "MasterClientResolver.handle" );
if ( exception instanceof IllegalProtocolVersionException )
{
log.info( "Handling " + exception + ", will pick new master client" );
IllegalProtocolVersionException illegalProtocolVersion = (IllegalProtocolVersionException) exception;
ProtocolVersion requiredProtocolVersion = new ProtocolVersion( illegalProtocolVersion.getReceived(),
ProtocolVersion.INTERNAL_PROTOCOL_VERSION );
getFor( requiredProtocolVersion );
}
else if ( exception instanceof InvalidEpochException )
{
log.info( "Handling " + exception + ", will go to PENDING and ask for election" );
invalidEpochHandler.handle();
}
else
{
log.debug( "Ignoring " + exception + "." );
}
}
private MasterClientFactory getFor( ProtocolVersion protocolVersion )
{
MasterClientFactory candidate = protocolToFactoryMapping.get( protocolVersion );
if ( candidate != null )
{
currentFactory = candidate;
}
return candidate;
}
private MasterClientFactory assignDefaultFactory()
{
return getFor( MasterClient214.PROTOCOL_VERSION );
}
private abstract static class StaticMasterClientFactory implements MasterClientFactory
{
protected final LogProvider logProvider;
protected final int readTimeoutSeconds;
protected final int lockReadTimeout;
protected final int maxConcurrentChannels;
protected final int chunkSize;
StaticMasterClientFactory( LogProvider logProvider, int readTimeoutSeconds, int lockReadTimeout,
int maxConcurrentChannels, int chunkSize )
{
this.logProvider = logProvider;
this.readTimeoutSeconds = readTimeoutSeconds;
this.lockReadTimeout = lockReadTimeout;
this.maxConcurrentChannels = maxConcurrentChannels;
this.chunkSize = chunkSize;
}
}
private final class F210 extends StaticMasterClientFactory
{
public F210( LogProvider logProvider, int readTimeoutSeconds, int lockReadTimeout, int maxConcurrentChannels,
int chunkSize )
{
super( logProvider, readTimeoutSeconds, lockReadTimeout, maxConcurrentChannels, chunkSize );
}
@Override
public MasterClient instantiate( String destinationHostNameOrIp, int destinationPort, String originHostNameOrIp,
Monitors monitors, StoreId storeId, LifeSupport life )
{
return life.add( new MasterClient210( destinationHostNameOrIp, destinationPort, originHostNameOrIp,
logProvider, storeId, readTimeoutSeconds, lockReadTimeout, maxConcurrentChannels, chunkSize,
responseUnpacker, monitors.newMonitor( ByteCounterMonitor.class, MasterClient210.class ),
monitors.newMonitor( RequestMonitor.class, MasterClient210.class ), logEntryReader.get() ) );
}
}
private final class F214 extends StaticMasterClientFactory
{
public F214( LogProvider logProvider, int readTimeoutSeconds, int lockReadTimeout, int maxConcurrentChannels,
int chunkSize )
{
super( logProvider, readTimeoutSeconds, lockReadTimeout, maxConcurrentChannels, chunkSize );
}
@Override
public MasterClient instantiate( String destinationHostNameOrIp, int destinationPort, String originHostNameOrIp,
Monitors monitors, StoreId storeId, LifeSupport life )
{
return life.add( new MasterClient214( destinationHostNameOrIp, destinationPort, originHostNameOrIp,
logProvider, storeId, readTimeoutSeconds, lockReadTimeout, maxConcurrentChannels, chunkSize,
responseUnpacker, monitors.newMonitor( ByteCounterMonitor.class, MasterClient214.class ),
monitors.newMonitor( RequestMonitor.class, MasterClient214.class ), logEntryReader.get() ) );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy