RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters) { this.properties = properties; this.stateMachineRegistry = stateMachineRegistry; final RpcType rpcType = RaftConfigKeys.Rpc.type(properties, LOG::info); this.factory = ServerFactory.cast(rpcType.newFactory(parameters)); this.serverRpc = factory.newRaftServerRpc(this); this.id = id != null? id: RaftPeerId.valueOf(getIdStringFrom(serverRpc)); this.lifeCycle = new LifeCycle(this.id + "-" + getClass().getSimpleName()); }
@Override public RpcType getRpcType() { return getFactory().getRpcType(); }
LogAppender newLogAppender( LeaderState state, RaftPeer peer, Timestamp lastRpcTime, long nextIndex, boolean attendVote) { final FollowerInfo f = new FollowerInfo(peer, lastRpcTime, nextIndex, attendVote); return getProxy().getFactory().newLogAppender(this, state, f); }
@Test public void testServerRestartOnException() throws Exception { RaftProperties properties = new RaftProperties(); final MiniRaftClusterWithGrpc cluster = MiniRaftClusterWithGrpc.FACTORY.newCluster(1, properties); cluster.start(); RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId(); GrpcConfigKeys.Server.setPort(properties, cluster.getLeader().getServerRpc().getInetSocketAddress().getPort()); // Create a raft server proxy with server rpc bound to a different address // compared to leader. This helps in locking the raft storage directory to // be used by next raft server proxy instance. final StateMachine stateMachine = cluster.getLeader().getStateMachine(); ServerImplUtils.newRaftServer(leaderId, cluster.getGroup(), gid -> stateMachine, properties, null); // Close the server rpc for leader so that new raft server can be bound to it. cluster.getLeader().getServerRpc().close(); // Create a raft server proxy with server rpc bound to same address as // the leader. This step would fail as the raft storage has been locked by // the raft server proxy created earlier. Raft server proxy should close // the rpc server on failure. testFailureCase("start a new server with the same address", () -> ServerImplUtils.newRaftServer(leaderId, cluster.getGroup(), gid -> stateMachine, properties, null).start(), IOException.class, OverlappingFileLockException.class); // Try to start a raft server rpc at the leader address. cluster.getServer(leaderId).getFactory().newRaftServerRpc(cluster.getServer(leaderId)); } }
@Test public void testServerRestartOnException() throws Exception { RaftProperties properties = new RaftProperties(); final MiniRaftClusterWithGRpc cluster = MiniRaftClusterWithGRpc.FACTORY.newCluster(1, properties); cluster.start(); RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId(); GrpcConfigKeys.Server.setPort(properties, cluster.getLeader().getServerRpc().getInetSocketAddress().getPort()); // Create a raft server proxy with server rpc bound to a different address // compared to leader. This helps in locking the raft storage directory to // be used by next raft server proxy instance. final StateMachine stateMachine = cluster.getLeader().getStateMachine(); ServerImplUtils.newRaftServer(leaderId, cluster.getGroup(), stateMachine, properties, null); // Close the server rpc for leader so that new raft server can be bound to it. cluster.getLeader().getServerRpc().close(); // Create a raft server proxy with server rpc bound to same address as // the leader. This step would fail as the raft storage has been locked by // the raft server proxy created earlier. Raft server proxy should close // the rpc server on failure. testFailureCase("start a new server with the same address", () -> ServerImplUtils.newRaftServer(leaderId, cluster.getGroup(), stateMachine, properties, null), IOException.class, IOException.class, OverlappingFileLockException.class); // Try to start a raft server rpc at the leader address. cluster.getServer(leaderId).getFactory().newRaftServerRpc(cluster.getServer(leaderId)); } }
RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftGroup group, RaftProperties properties, Parameters parameters) throws IOException { this.properties = properties; this.stateMachineRegistry = stateMachineRegistry; final RpcType rpcType = RaftConfigKeys.Rpc.type(properties); this.factory = ServerFactory.cast(rpcType.newFactory(parameters)); this.serverRpc = factory.newRaftServerRpc(this); this.id = id != null? id: RaftPeerId.valueOf(getIdStringFrom(serverRpc)); try { this.impl = CompletableFuture.completedFuture(initImpl(group)); } catch (IOException ioe) { try { serverRpc.close(); } catch (IOException closeIoe) { LOG.warn(this.id + ": Failed to close server rpc.", closeIoe); ioe.addSuppressed(closeIoe); } finally { throw ioe; } } }
LogAppender newLogAppender( LeaderState state, RaftPeer peer, Timestamp lastRpcTime, long nextIndex, boolean attendVote) { final FollowerInfo f = new FollowerInfo(getId(), peer, lastRpcTime, nextIndex, attendVote, rpcSlownessTimeoutMs); return getProxy().getFactory().newLogAppender(this, state, f); }
@Override public RpcType getRpcType() { return getFactory().getRpcType(); }