Search in sources :

Example 1 with RaftClusterEvent

use of io.atomix.protocols.raft.cluster.RaftClusterEvent in project atomix by atomix.

the class RaftClusterContext method configure.

/**
 * Configures the cluster state.
 *
 * @param configuration The cluster configuration.
 * @return The cluster state.
 */
public RaftClusterContext configure(Configuration configuration) {
    checkNotNull(configuration, "configuration cannot be null");
    // Configurations can be persisted and applying old configurations can revert newer configurations.
    if (this.configuration != null && configuration.index() <= this.configuration.index()) {
        return this;
    }
    Instant time = Instant.ofEpochMilli(configuration.time());
    // Iterate through members in the new configuration, add any missing members, and update existing members.
    boolean transition = false;
    for (RaftMember member : configuration.members()) {
        if (member.equals(this.member)) {
            transition = this.member.getType().ordinal() < member.getType().ordinal();
            this.member.update(member.getType(), time);
            members.add(this.member);
        } else {
            // If the member state doesn't already exist, create it.
            RaftMemberContext state = membersMap.get(member.nodeId());
            if (state == null) {
                DefaultRaftMember defaultMember = new DefaultRaftMember(member.nodeId(), member.getType(), time);
                state = new RaftMemberContext(defaultMember, this);
                state.resetState(raft.getLog());
                this.members.add(state.getMember());
                this.remoteMembers.add(state);
                membersMap.put(member.nodeId(), state);
                listeners.forEach(l -> l.onEvent(new RaftClusterEvent(RaftClusterEvent.Type.JOIN, defaultMember, time.toEpochMilli())));
            }
            // If the member type has changed, update the member type and reset its state.
            if (state.getMember().getType() != member.getType()) {
                state.getMember().update(member.getType(), time);
                state.resetState(raft.getLog());
            }
            // Update the optimized member collections according to the member type.
            for (List<RaftMemberContext> memberType : memberTypes.values()) {
                memberType.remove(state);
            }
            List<RaftMemberContext> memberType = memberTypes.get(member.getType());
            if (memberType == null) {
                memberType = new CopyOnWriteArrayList<>();
                memberTypes.put(member.getType(), memberType);
            }
            memberType.add(state);
        }
    }
    // can commit the configuration change prior to shutting down.
    if (transition) {
        raft.transition(this.member.getType());
    }
    // Iterate through configured members and remove any that no longer exist in the configuration.
    int i = 0;
    while (i < this.remoteMembers.size()) {
        RaftMemberContext member = this.remoteMembers.get(i);
        if (!configuration.members().contains(member.getMember())) {
            this.members.remove(member.getMember());
            this.remoteMembers.remove(i);
            for (List<RaftMemberContext> memberType : memberTypes.values()) {
                memberType.remove(member);
            }
            membersMap.remove(member.getMember().nodeId());
            listeners.forEach(l -> l.onEvent(new RaftClusterEvent(RaftClusterEvent.Type.LEAVE, member.getMember(), time.toEpochMilli())));
        } else {
            i++;
        }
    }
    // If the local member was removed from the cluster, remove it from the members list.
    if (!configuration.members().contains(member)) {
        members.remove(member);
    }
    this.configuration = configuration;
    // Store the configuration if it's already committed.
    if (raft.getCommitIndex() >= configuration.index()) {
        raft.getMetaStore().storeConfiguration(configuration);
    }
    return this;
}
Also used : RaftMember(io.atomix.protocols.raft.cluster.RaftMember) RaftClusterEvent(io.atomix.protocols.raft.cluster.RaftClusterEvent) Instant(java.time.Instant)

Aggregations

RaftClusterEvent (io.atomix.protocols.raft.cluster.RaftClusterEvent)1 RaftMember (io.atomix.protocols.raft.cluster.RaftMember)1 Instant (java.time.Instant)1