private static String getIdStringFrom(RaftServerRpc rpc) { InetSocketAddress address = null; try { address = rpc.getInetSocketAddress(); } catch(Exception e) { LOG.warn("Failed to get InetSocketAddress from " + rpc.getRpcType() + " rpc server", e); } return address != null? address.getHostName() + "_" + address.getPort() : rpc.getRpcType() + "-" + UUID.randomUUID(); }
@Override public void close() { LOG.info("{}: close", getId()); JavaUtils.getAndConsume(impl, RaftServerImpl::shutdown); try { getServerRpc().close(); } catch (IOException ignored) { LOG.warn("Failed to close RPC server for " + getId(), ignored); } }
void setRaftConf(long logIndex, RaftConfiguration conf) { configurationManager.addConfiguration(logIndex, conf); server.getServerRpc().addPeers(conf.getPeers()); LOG.info("{}: set configuration {} at {}", getSelfId(), conf, logIndex); LOG.trace("{}: {}", getSelfId(), configurationManager); }
@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)); } }
public static RaftPeer toRaftPeer(RaftServerProxy s) { return new RaftPeer(s.getId(), s.getServerRpc().getInetSocketAddress()); }
private void handleException(Exception e) { LOG.trace("TRACE", e); server.getServerRpc().handleException(follower.getPeer().getId(), e, false); }
private InstallSnapshotReplyProto installSnapshot(SnapshotInfo snapshot) throws InterruptedIOException { String requestId = UUID.randomUUID().toString(); InstallSnapshotReplyProto reply = null; try { for (InstallSnapshotRequestProto request : new SnapshotRequestIter(snapshot, requestId)) { follower.updateLastRpcSendTime(); reply = server.getServerRpc().installSnapshot(request); follower.updateLastRpcResponseTime(); if (!reply.getServerReply().getSuccess()) { return reply; } } } catch (InterruptedIOException iioe) { throw iioe; } catch (Exception ioe) { LOG.warn("{}: Failed to installSnapshot {}: {}", this, snapshot, ioe); handleException(ioe); return null; } if (reply != null) { follower.setSnapshotIndex(snapshot.getTermIndex().getIndex()); LOG.info("{}: install snapshot-{} successfully on follower {}", server.getId(), snapshot.getTermIndex().getIndex(), follower.getPeer()); } return reply; }
final AppendEntriesReplyProto r = server.getServerRpc().appendEntries(request); follower.updateLastRpcResponseTime();
@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)); } }
public static RaftPeer toRaftPeer(RaftServerProxy s) { return new RaftPeer(s.getId(), s.getServerRpc().getInetSocketAddress()); }
private void handleException(Exception e) { LOG.trace("TRACE", e); server.getServerRpc().handleException(follower.getPeer().getId(), e, false); }
private InstallSnapshotReplyProto installSnapshot(SnapshotInfo snapshot) throws InterruptedIOException { String requestId = UUID.randomUUID().toString(); InstallSnapshotReplyProto reply = null; try { for (InstallSnapshotRequestProto request : new SnapshotRequestIter(snapshot, requestId)) { follower.updateLastRpcSendTime(); reply = server.getServerRpc().installSnapshot(request); follower.updateLastRpcResponseTime(); if (!reply.getServerReply().getSuccess()) { return reply; } } } catch (InterruptedIOException iioe) { throw iioe; } catch (Exception ioe) { LOG.warn("{}: Failed to installSnapshot {}: {}", this, snapshot, ioe); handleException(ioe); return null; } if (reply != null) { follower.updateMatchIndex(snapshot.getTermIndex().getIndex()); follower.updateNextIndex(snapshot.getTermIndex().getIndex() + 1); LOG.info("{}: install snapshot-{} successfully on follower {}", server.getId(), snapshot.getTermIndex().getIndex(), follower.getPeer()); } return reply; }
final AppendEntriesReplyProto r = server.getServerRpc().appendEntries(request); follower.updateLastRpcResponseTime();
private static String getIdStringFrom(RaftServerRpc rpc) { InetSocketAddress address = null; try { address = rpc.getInetSocketAddress(); } catch(Exception e) { LOG.warn("Failed to get InetSocketAddress from " + rpc.getRpcType() + " rpc server", e); } return address != null? address.getHostName() + "_" + address.getPort() : rpc.getRpcType() + "-" + UUID.randomUUID(); }
@Override public void close() { lifeCycle.checkStateAndClose(() -> { LOG.info("{}: close", getId()); impls.close(); try { getServerRpc().close(); } catch(IOException ignored) { LOG.warn(getId() + ": Failed to close " + getRpcType() + " server", ignored); } }); }
private CompletableFuture<RaftServerImpl> newRaftServerImpl(RaftGroup group) { return CompletableFuture.supplyAsync(() -> { try { serverRpc.addPeers(group.getPeers()); return new RaftServerImpl(group, stateMachineRegistry.apply(group.getGroupId()), this); } catch(IOException e) { throw new CompletionException(getId() + ": Failed to initialize server for " + group, e); } }); }
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; } } }
public static RaftServerProxy newRaftServer( RaftPeerId id, RaftGroup group, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters) throws IOException { final RaftServerProxy proxy; try { // attempt multiple times to avoid temporary bind exception proxy = JavaUtils.attempt( () -> new RaftServerProxy(id, stateMachineRegistry, group, properties, parameters), 5, 500L, "new RaftServerProxy", RaftServerProxy.LOG); } catch (InterruptedException e) { throw IOUtils.toInterruptedIOException( "Interrupted when creating RaftServer " + id + ", " + group, e); } catch (IOException e) { throw new IOException("Failed to create RaftServer " + id + ", " + group, e); } // add peers into rpc service if (!group.getPeers().isEmpty()) { proxy.getServerRpc().addPeers(group.getPeers()); } return proxy; }
getServerRpc().addPeers(request.getGroup().getPeers()); newImpl.start(); impl.complete(newImpl);
void updateConfiguration(LogEntryProto[] entries) { if (entries != null && entries.length > 0) { configurationManager.removeConfigurations(entries[0].getIndex()); for (LogEntryProto entry : entries) { if (ProtoUtils.isConfigurationLogEntry(entry)) { final RaftConfiguration conf = ServerProtoUtils.toRaftConfiguration( entry.getIndex(), entry.getConfigurationEntry()); configurationManager.addConfiguration(entry.getIndex(), conf); server.getServerRpc().addPeers(conf.getPeers()); } } } }