Search in sources :

Example 6 with MemberId

use of io.atomix.cluster.MemberId in project atomix by atomix.

the class RaftClusterContext method listen.

@Override
public synchronized CompletableFuture<Void> listen(Collection<MemberId> cluster) {
    if (joinFuture != null) {
        return joinFuture;
    }
    // If no configuration was loaded from disk, create a new configuration.
    if (configuration == null) {
        member.setType(RaftMember.Type.PASSIVE);
        // Create a set of cluster members, excluding the local member which is joining a cluster.
        Set<RaftMember> activeMembers = cluster.stream().filter(m -> !m.equals(member.memberId())).map(m -> new DefaultRaftMember(m, RaftMember.Type.ACTIVE, member.getLastUpdated())).collect(Collectors.toSet());
        // fail the join.
        if (activeMembers.isEmpty()) {
            return Futures.exceptionalFuture(new IllegalStateException("cannot join empty cluster"));
        }
        // Create a new configuration and configure the cluster. Once the cluster is configured, the configuration
        // will be stored on disk to ensure the cluster can fall back to the provided configuration if necessary.
        configure(new Configuration(0, 0, member.getLastUpdated().toEpochMilli(), activeMembers));
    }
    return join();
}
Also used : RaftClusterEvent(io.atomix.protocols.raft.cluster.RaftClusterEvent) RaftMember(io.atomix.protocols.raft.cluster.RaftMember) RaftCluster(io.atomix.protocols.raft.cluster.RaftCluster) RaftClusterEventListener(io.atomix.protocols.raft.cluster.RaftClusterEventListener) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) JoinRequest(io.atomix.protocols.raft.protocol.JoinRequest) RaftServer(io.atomix.protocols.raft.RaftServer) ContextualLoggerFactory(io.atomix.utils.logging.ContextualLoggerFactory) LeaveRequest(io.atomix.protocols.raft.protocol.LeaveRequest) ArrayList(java.util.ArrayList) RaftResponse(io.atomix.protocols.raft.protocol.RaftResponse) Map(java.util.Map) MemberId(io.atomix.cluster.MemberId) RaftError(io.atomix.protocols.raft.RaftError) Scheduled(io.atomix.utils.concurrent.Scheduled) Futures(io.atomix.utils.concurrent.Futures) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) LoggerContext(io.atomix.utils.logging.LoggerContext) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Set(java.util.Set) Instant(java.time.Instant) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) Collectors(java.util.stream.Collectors) Configuration(io.atomix.protocols.raft.storage.system.Configuration) Consumer(java.util.function.Consumer) List(java.util.List) RaftContext(io.atomix.protocols.raft.impl.RaftContext) Comparator(java.util.Comparator) Collections(java.util.Collections) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) RaftMember(io.atomix.protocols.raft.cluster.RaftMember) Configuration(io.atomix.protocols.raft.storage.system.Configuration)

Example 7 with MemberId

use of io.atomix.cluster.MemberId in project atomix by atomix.

the class RaftClusterContext method bootstrap.

@Override
public CompletableFuture<Void> bootstrap(Collection<MemberId> cluster) {
    if (joinFuture != null) {
        return joinFuture;
    }
    if (configuration == null) {
        member.setType(RaftMember.Type.ACTIVE);
        // Create a set of active members.
        Set<RaftMember> activeMembers = cluster.stream().filter(m -> !m.equals(member.memberId())).map(m -> new DefaultRaftMember(m, RaftMember.Type.ACTIVE, member.getLastUpdated())).collect(Collectors.toSet());
        // Add the local member to the set of active members.
        activeMembers.add(member);
        // Create a new configuration and store it on disk to ensure the cluster can fall back to the configuration.
        configure(new Configuration(0, 0, member.getLastUpdated().toEpochMilli(), activeMembers));
    }
    return join();
}
Also used : RaftClusterEvent(io.atomix.protocols.raft.cluster.RaftClusterEvent) RaftMember(io.atomix.protocols.raft.cluster.RaftMember) RaftCluster(io.atomix.protocols.raft.cluster.RaftCluster) RaftClusterEventListener(io.atomix.protocols.raft.cluster.RaftClusterEventListener) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) JoinRequest(io.atomix.protocols.raft.protocol.JoinRequest) RaftServer(io.atomix.protocols.raft.RaftServer) ContextualLoggerFactory(io.atomix.utils.logging.ContextualLoggerFactory) LeaveRequest(io.atomix.protocols.raft.protocol.LeaveRequest) ArrayList(java.util.ArrayList) RaftResponse(io.atomix.protocols.raft.protocol.RaftResponse) Map(java.util.Map) MemberId(io.atomix.cluster.MemberId) RaftError(io.atomix.protocols.raft.RaftError) Scheduled(io.atomix.utils.concurrent.Scheduled) Futures(io.atomix.utils.concurrent.Futures) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) LoggerContext(io.atomix.utils.logging.LoggerContext) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Set(java.util.Set) Instant(java.time.Instant) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) Collectors(java.util.stream.Collectors) Configuration(io.atomix.protocols.raft.storage.system.Configuration) Consumer(java.util.function.Consumer) List(java.util.List) RaftContext(io.atomix.protocols.raft.impl.RaftContext) Comparator(java.util.Comparator) Collections(java.util.Collections) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) RaftMember(io.atomix.protocols.raft.cluster.RaftMember) Configuration(io.atomix.protocols.raft.storage.system.Configuration)

Example 8 with MemberId

use of io.atomix.cluster.MemberId in project atomix by atomix.

the class RaftClusterContext method join.

@Override
public synchronized CompletableFuture<Void> join(Collection<MemberId> cluster) {
    if (joinFuture != null) {
        return joinFuture;
    }
    // If no configuration was loaded from disk, create a new configuration.
    if (configuration == null) {
        member.setType(RaftMember.Type.PROMOTABLE);
        // Create a set of cluster members, excluding the local member which is joining a cluster.
        Set<RaftMember> activeMembers = cluster.stream().filter(m -> !m.equals(member.memberId())).map(m -> new DefaultRaftMember(m, RaftMember.Type.ACTIVE, member.getLastUpdated())).collect(Collectors.toSet());
        // fail the join.
        if (activeMembers.isEmpty()) {
            return Futures.exceptionalFuture(new IllegalStateException("cannot join empty cluster"));
        }
        // Create a new configuration and configure the cluster. Once the cluster is configured, the configuration
        // will be stored on disk to ensure the cluster can fall back to the provided configuration if necessary.
        configure(new Configuration(0, 0, member.getLastUpdated().toEpochMilli(), activeMembers));
    }
    return join().thenCompose(v -> {
        if (member.getType() == RaftMember.Type.ACTIVE) {
            return CompletableFuture.completedFuture(null);
        } else {
            return member.promote(RaftMember.Type.ACTIVE);
        }
    });
}
Also used : RaftClusterEvent(io.atomix.protocols.raft.cluster.RaftClusterEvent) RaftMember(io.atomix.protocols.raft.cluster.RaftMember) RaftCluster(io.atomix.protocols.raft.cluster.RaftCluster) RaftClusterEventListener(io.atomix.protocols.raft.cluster.RaftClusterEventListener) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) JoinRequest(io.atomix.protocols.raft.protocol.JoinRequest) RaftServer(io.atomix.protocols.raft.RaftServer) ContextualLoggerFactory(io.atomix.utils.logging.ContextualLoggerFactory) LeaveRequest(io.atomix.protocols.raft.protocol.LeaveRequest) ArrayList(java.util.ArrayList) RaftResponse(io.atomix.protocols.raft.protocol.RaftResponse) Map(java.util.Map) MemberId(io.atomix.cluster.MemberId) RaftError(io.atomix.protocols.raft.RaftError) Scheduled(io.atomix.utils.concurrent.Scheduled) Futures(io.atomix.utils.concurrent.Futures) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) LoggerContext(io.atomix.utils.logging.LoggerContext) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Set(java.util.Set) Instant(java.time.Instant) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) Collectors(java.util.stream.Collectors) Configuration(io.atomix.protocols.raft.storage.system.Configuration) Consumer(java.util.function.Consumer) List(java.util.List) RaftContext(io.atomix.protocols.raft.impl.RaftContext) Comparator(java.util.Comparator) Collections(java.util.Collections) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) RaftMember(io.atomix.protocols.raft.cluster.RaftMember) Configuration(io.atomix.protocols.raft.storage.system.Configuration)

Example 9 with MemberId

use of io.atomix.cluster.MemberId in project atomix by atomix.

the class HashBasedPrimaryElection method recomputeTerm.

/**
 * Recomputes the current term.
 */
private synchronized void recomputeTerm(PartitionGroupMembership membership) {
    if (membership == null) {
        return;
    }
    // Create a list of candidates based on the availability of members in the group.
    List<GroupMember> candidates = new ArrayList<>();
    for (MemberId memberId : membership.members()) {
        Member member = clusterMembershipService.getMember(memberId);
        if (member != null && member.isReachable()) {
            candidates.add(new GroupMember(memberId, MemberGroupId.from(memberId.id())));
        }
    }
    // Sort the candidates by a hash of their member ID.
    candidates.sort((a, b) -> {
        int aoffset = Hashing.murmur3_32().hashString(a.memberId().id(), StandardCharsets.UTF_8).asInt() % partitionId.id();
        int boffset = Hashing.murmur3_32().hashString(b.memberId().id(), StandardCharsets.UTF_8).asInt() % partitionId.id();
        return aoffset - boffset;
    });
    // Store the current term in a local variable avoid repeated volatile reads.
    PrimaryTerm currentTerm = this.currentTerm;
    // Compute the primary from the sorted candidates list.
    GroupMember primary = candidates.isEmpty() ? null : candidates.get(0);
    // Remove the primary from the candidates list.
    candidates = candidates.isEmpty() ? Collections.emptyList() : candidates.subList(1, candidates.size());
    // If the primary has changed, increment the term. Otherwise, use the current term from the replicated counter.
    long term = currentTerm != null && Objects.equals(currentTerm.primary(), primary) && Objects.equals(currentTerm.candidates(), candidates) ? currentTerm() : incrementTerm();
    // Create the new primary term. If the term has changed update the term and trigger an event.
    PrimaryTerm newTerm = new PrimaryTerm(term, primary, candidates);
    if (!Objects.equals(currentTerm, newTerm)) {
        this.currentTerm = newTerm;
        LOGGER.debug("{} - Recomputed term for partition {}: {}", clusterMembershipService.getLocalMember().id(), partitionId, newTerm);
        post(new PrimaryElectionEvent(PrimaryElectionEvent.Type.CHANGED, partitionId, newTerm));
        broadcastCounters();
    }
}
Also used : GroupMember(io.atomix.primitive.partition.GroupMember) MemberId(io.atomix.cluster.MemberId) PrimaryElectionEvent(io.atomix.primitive.partition.PrimaryElectionEvent) ArrayList(java.util.ArrayList) GroupMember(io.atomix.primitive.partition.GroupMember) Member(io.atomix.cluster.Member) PrimaryTerm(io.atomix.primitive.partition.PrimaryTerm)

Example 10 with MemberId

use of io.atomix.cluster.MemberId in project atomix by atomix.

the class PrimaryElectorServiceTest method newService.

PrimaryElectorService newService() {
    PrimaryElectorService elector = new PrimaryElectorService();
    elector.init(new ServiceContext() {

        @Override
        public PrimitiveId serviceId() {
            return PrimitiveId.from(1L);
        }

        @Override
        public String serviceName() {
            return "test-primary-elector";
        }

        @SuppressWarnings("rawtypes")
        @Override
        public PrimitiveType serviceType() {
            return PrimaryElectorType.instance();
        }

        @Override
        public MemberId localMemberId() {
            return null;
        }

        @Override
        public <C extends ServiceConfig> C serviceConfig() {
            return null;
        }

        @Override
        public long currentIndex() {
            return 0;
        }

        @Override
        public Session<?> currentSession() {
            return null;
        }

        @Override
        public OperationType currentOperation() {
            return null;
        }

        @Override
        public LogicalClock logicalClock() {
            return null;
        }

        @Override
        public WallClock wallClock() {
            return null;
        }
    });
    elector.tick(WallClockTimestamp.from(System.currentTimeMillis()));
    return elector;
}
Also used : ServiceContext(io.atomix.primitive.service.ServiceContext) LogicalClock(io.atomix.utils.time.LogicalClock) WallClock(io.atomix.utils.time.WallClock) MemberId(io.atomix.cluster.MemberId) PrimitiveType(io.atomix.primitive.PrimitiveType) OperationType(io.atomix.primitive.operation.OperationType) PrimitiveId(io.atomix.primitive.PrimitiveId) Session(io.atomix.primitive.session.Session)

Aggregations

MemberId (io.atomix.cluster.MemberId)24 CompletableFuture (java.util.concurrent.CompletableFuture)10 ArrayList (java.util.ArrayList)9 List (java.util.List)7 Consumer (java.util.function.Consumer)7 Collectors (java.util.stream.Collectors)7 PrimitiveType (io.atomix.primitive.PrimitiveType)6 Futures (io.atomix.utils.concurrent.Futures)6 SessionId (io.atomix.primitive.session.SessionId)5 RaftMember (io.atomix.protocols.raft.cluster.RaftMember)5 Configuration (io.atomix.protocols.raft.storage.system.Configuration)5 Instant (java.time.Instant)5 Collections (java.util.Collections)5 Map (java.util.Map)5 TestClusterMembershipService (io.atomix.cluster.TestClusterMembershipService)4 PrimitiveBuilder (io.atomix.primitive.PrimitiveBuilder)4 PrimitiveManagementService (io.atomix.primitive.PrimitiveManagementService)4 PrimitiveConfig (io.atomix.primitive.config.PrimitiveConfig)4 PartitionId (io.atomix.primitive.partition.PartitionId)4 AbstractPrimitiveService (io.atomix.primitive.service.AbstractPrimitiveService)4