All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.scalecube.cluster.ClusterMembershipTable Maven / Gradle / Ivy

package io.scalecube.cluster;

import static io.scalecube.cluster.ClusterMemberStatus.REMOVED;
import static io.scalecube.cluster.ClusterMemberStatus.SUSPECTED;
import static io.scalecube.cluster.ClusterMemberStatus.TRUSTED;

import io.scalecube.cluster.fdetector.FailureDetectorEvent;
import io.scalecube.transport.TransportEndpoint;

import com.google.common.base.Predicate;
import com.google.common.collect.Maps;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

final class ClusterMembershipTable {

  private static final Predicate TRUSTED_OR_SUSPECTED_PREDICATE = new Predicate() {
    @Override
    public boolean apply(ClusterMember input) {
      return input.status() == TRUSTED || input.status() == SUSPECTED;
    }
  };

  private static final Maps.EntryTransformer MEMBER_TO_ENDPOINT_TRANSFORMER =
      new Maps.EntryTransformer() {
        @Override
        public TransportEndpoint transformEntry(String key, ClusterMember value) {
          return value.endpoint();
        }
      };


  private final ConcurrentMap membership = new ConcurrentHashMap<>();

  public List merge(ClusterMembershipData data) {
    List updates = new ArrayList<>();
    for (ClusterMember record : data.getMembership()) {
      updates.addAll(merge(record));
    }
    return updates;
  }

  public List merge(ClusterMember r1) {
    List updates = new ArrayList<>(1);
    ClusterMember r0 = membership.putIfAbsent(r1.id(), r1);
    if (r0 == null) {
      updates.add(r1);
    } else if (r0.compareTo(r1) < 0) {
      if (membership.replace(r1.id(), r0, r1)) {
        updates.add(r1);
      } else {
        return merge(r1);
      }
    }
    return updates;
  }

  public List merge(FailureDetectorEvent event) {
    ClusterMember r0 = membership.get(event.endpoint().id());
    if (r0 != null) {
      return merge(new ClusterMember(event.endpoint(), event.status(), r0.metadata()));
    } else {
      return Collections.emptyList();
    }
  }

  public ClusterMember get(TransportEndpoint endpoint) {
    return membership.get(endpoint.id());
  }

  public ClusterMember get(String id) {
    return membership.get(id);
  }

  public List remove(TransportEndpoint endpoint) {
    List updates = new ArrayList<>(1);
    ClusterMember r0 = membership.remove(endpoint.id());
    if (r0 != null) {
      updates.add(new ClusterMember(endpoint, REMOVED, r0.metadata()));
    }
    return updates;
  }

  public List asList() {
    return new ArrayList<>(membership.values());
  }

  /**
   * Getting {@code TRUSTED} or {@code SUSPECTED} member's endpoints.
   */
  public Collection getTrustedOrSuspectedEndpoints() {
    Map suspectedOrTrusted = Maps.filterValues(membership, TRUSTED_OR_SUSPECTED_PREDICATE);
    return Maps.transformEntries(suspectedOrTrusted, MEMBER_TO_ENDPOINT_TRANSFORMER).values();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy