/** * Handle a raft configuration change request from client. */ @Override public CompletableFuture<RaftClientReply> setConfigurationAsync( SetConfigurationRequest request) throws IOException { return getImpl().setConfigurationAsync(request); }
@Override public RpcType getRpcType() { return getFactory().getRpcType(); }
public void killServer(RaftPeerId id) { LOG.info("killServer " + id); servers.get(id).close(); }
@Override public ServerInformationReply getInfo(ServerInformationRequest request) throws IOException { return RaftServerImpl.waitForReply(getId(), request, getInfoAsync(request), r -> null); }
@Override public GroupInfoReply getGroupInfo(GroupInfoRequest request) throws IOException { return RaftServerImpl.waitForReply(getId(), request, getGroupInfoAsync(request), r -> null); }
@Override public CompletableFuture<RaftClientReply> reinitializeAsync( ReinitializeRequest request) throws IOException { LOG.info("{}: reinitializeAsync {}", getId(), request); getImpl().assertGroup(request.getRequestorId(), request.getRaftGroupId()); if (!reinitializeRequest.compareAndSet(null, request)) { throw new IOException("Another reinitialize is already in progress."); newImpl = initImpl(request.getGroup()); } catch (IOException ioe) { final RaftException re = new RaftException( "Failed to reinitialize, request=" + request, ioe); impl.completeExceptionally(new IOException( "Server " + getId() + " is not initialized.", re)); return new RaftClientReply(request, re, null); getServerRpc().addPeers(request.getGroup().getPeers()); newImpl.start(); impl.complete(newImpl);
@Override public void start() throws IOException { getImpls().parallelStream().forEach(RaftServerImpl::start); lifeCycle.startAndTransition(() -> { LOG.info("{}: start RPC server", getId()); getServerRpc().start(); }, IOException.class); }
@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); } }
synchronized CompletableFuture<RaftServerImpl> remove(RaftGroupId groupId) { final CompletableFuture<RaftServerImpl> future = map.remove(groupId); LOG.info("{}: remove {}", getId(), toString(groupId, future)); return future; }
@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); } }); }
RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy) throws IOException { final RaftPeerId id = proxy.getId(); LOG.debug("{}: new RaftServerImpl for {}", id, group); this.groupId = group.getGroupId(); this.lifeCycle = new LifeCycle(id); this.stateMachine = stateMachine; final RaftProperties properties = proxy.getProperties(); minTimeoutMs = RaftServerConfigKeys.Rpc.timeoutMin(properties).toInt(TimeUnit.MILLISECONDS); maxTimeoutMs = RaftServerConfigKeys.Rpc.timeoutMax(properties).toInt(TimeUnit.MILLISECONDS); Preconditions.assertTrue(maxTimeoutMs > minTimeoutMs, "max timeout: %s, min timeout: %s", maxTimeoutMs, minTimeoutMs); this.proxy = proxy; this.state = new ServerState(id, group, properties, this, stateMachine); this.retryCache = initRetryCache(properties); this.jmxAdapter = new RaftServerJmxAdapter(); }
@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)); } }
@Override public CompletableFuture<RaftClientReply> groupManagementAsync(GroupManagementRequest request) { final RaftGroupId groupId = request.getRaftGroupId(); if (groupId == null) { return JavaUtils.completeExceptionally(new GroupMismatchException( getId() + ": Request group id == null")); } final GroupManagementRequest.Add add = request.getAdd(); if (add != null) { return groupAddAsync(request, add.getGroup()); } final GroupManagementRequest.Remove remove = request.getRemove(); if (remove != null) { return groupRemoveAsync(request, remove.getGroupId(), remove.isDeleteDirectory()); } return JavaUtils.completeExceptionally(new UnsupportedOperationException( getId() + ": Request not supported " + request)); }
public GrpcLogAppender(RaftServerImpl server, LeaderState leaderState, FollowerInfo f) { super(server, leaderState, f); this.rpcService = (GrpcService) server.getServerRpc(); maxPendingRequestsNum = GrpcConfigKeys.Server.leaderOutstandingAppendsMax( server.getProxy().getProperties()); requestTimeoutDuration = RaftServerConfigKeys.Rpc.requestTimeout(server.getProxy().getProperties()); pendingRequests = new ConcurrentHashMap<>(); }
@Test public void testLateServerStart() throws Exception { final int numServer = 3; LOG.info("Running testLateServerStart"); final MiniRaftCluster cluster = newCluster(numServer); cluster.initServers(); // start all except one servers final Iterator<RaftServerProxy> i = cluster.getServers().iterator(); for(int j = 1; j < numServer; j++) { i.next().start(); } final RaftServerImpl leader = waitForLeader(cluster); final TimeDuration sleepTime = TimeDuration.valueOf(3, TimeUnit.SECONDS); LOG.info("sleep " + sleepTime); sleepTime.sleep(); // start the last server final RaftServerProxy lastServer = i.next(); lastServer.start(); final RaftPeerId lastServerLeaderId = JavaUtils.attempt( () -> getLeader(lastServer.getImpls().iterator().next().getState()), 10, 1000, "getLeaderId", LOG); LOG.info(cluster.printServers()); Assert.assertEquals(leader.getId(), lastServerLeaderId); }
@Override public RaftClientReply reinitialize(ReinitializeRequest request) throws IOException { return RaftServerImpl.waitForReply(getId(), request, reinitializeAsync(request), e -> new RaftClientReply(request, e, null)); }
@Override public RaftClientReply groupManagement(GroupManagementRequest request) throws IOException { return RaftServerImpl.waitForReply(getId(), request, groupManagementAsync(request), e -> new RaftClientReply(request, e, null)); }
/** Check the storage dir and add groups*/ void initGroups(RaftGroup group) { final Optional<RaftGroup> raftGroup = Optional.ofNullable(group); final Optional<RaftGroupId> raftGroupId = raftGroup.map(RaftGroup::getGroupId); RaftServerConfigKeys.storageDirs(properties).parallelStream() .forEach((dir) -> Optional.ofNullable(dir.listFiles()) .map(Arrays::stream).orElse(Stream.empty()) .filter(File::isDirectory) .forEach(sub -> { try { LOG.info("{}: found a subdirectory {}", getId(), sub); final RaftGroupId groupId = RaftGroupId.valueOf(UUID.fromString(sub.getName())); if (!raftGroupId.filter(groupId::equals).isPresent()) { addGroup(RaftGroup.valueOf(groupId)); } } catch (Throwable t) { LOG.warn(getId() + ": Failed to initialize the group directory " + sub.getAbsolutePath() + ". Ignoring it", t); } })); raftGroup.ifPresent(this::addGroup); }