Search in sources :

Example 6 with View

use of org.jgroups.View in project JGroups by belaban.

the class CoordGmsImpl method handleMembershipChange.

public void handleMembershipChange(Collection<Request> requests) {
    boolean joinAndStateTransferInitiated = false;
    boolean useFlushIfPresent = gms.use_flush_if_present;
    Collection<Address> new_mbrs = new LinkedHashSet<>(requests.size());
    Collection<Address> suspected_mbrs = new LinkedHashSet<>(requests.size());
    Collection<Address> leaving_mbrs = new LinkedHashSet<>(requests.size());
    // is the coord leaving
    boolean self_leaving = false;
    for (Request req : requests) {
        switch(req.type) {
            case Request.JOIN:
                new_mbrs.add(req.mbr);
                if (req.useFlushIfPresent)
                    useFlushIfPresent = true;
                break;
            case Request.JOIN_WITH_STATE_TRANSFER:
                new_mbrs.add(req.mbr);
                joinAndStateTransferInitiated = true;
                if (req.useFlushIfPresent)
                    useFlushIfPresent = true;
                break;
            case Request.LEAVE:
                leaving_mbrs.add(req.mbr);
                if (Objects.equals(gms.local_addr, req.mbr))
                    self_leaving = true;
                break;
            case Request.SUSPECT:
                suspected_mbrs.add(req.mbr);
                break;
        }
    }
    // remove myself - cannot join myself (already joined)
    new_mbrs.remove(gms.local_addr);
    if (gms.getViewId() == null) {
        // we're probably not the coord anymore (we just left ourselves), let someone else do it
        // (client will retry when it doesn't get a response)
        log.debug("gms.view_id is null, I'm not the coordinator anymore (leaving=%b); " + "the new coordinator will handle the leave request", self_leaving);
        return;
    }
    List<Address> current_members = gms.members.getMembers();
    // remove all elements of leaving_mbrs which are not current members
    leaving_mbrs.retainAll(current_members);
    if (suspected_mbrs.remove(gms.local_addr))
        log.warn("I am the coord and I'm being suspected -- will probably leave shortly");
    // remove all elements of suspected_mbrs which are not current members
    suspected_mbrs.retainAll(current_members);
    // for the members that have already joined, return the current digest and membership
    for (Iterator<Address> it = new_mbrs.iterator(); it.hasNext(); ) {
        Address mbr = it.next();
        if (gms.members.contains(mbr)) {
            // already joined: return current digest and membership
            log.trace("%s: %s already present; returning existing view %s", gms.local_addr, mbr, gms.view);
            Tuple<View, Digest> tuple = gms.getViewAndDigest();
            if (tuple != null)
                gms.sendJoinResponse(new JoinRsp(tuple.getVal1(), tuple.getVal2()), mbr);
            else
                log.warn("%s: did not find a digest matching view %s; dropping JOIN-RSP", gms.local_addr, gms.view);
            // remove it anyway, even if we didn't find a digest matching the view (joiner will retry)
            it.remove();
        }
    }
    if (new_mbrs.isEmpty() && leaving_mbrs.isEmpty() && suspected_mbrs.isEmpty()) {
        log.trace("%s: found no members to add or remove, will not create new view", gms.local_addr);
        return;
    }
    View new_view = gms.getNextView(new_mbrs, leaving_mbrs, suspected_mbrs);
    if (new_view.size() == 0 && gms.local_addr != null && gms.local_addr.equals(new_view.getCreator())) {
        if (self_leaving)
            // in case connect() is called again
            gms.initState();
        return;
    }
    log.trace("%s: joiners=%s, suspected=%s, leaving=%s, new view: %s", gms.local_addr, new_mbrs, suspected_mbrs, leaving_mbrs, new_view);
    JoinRsp join_rsp = null;
    boolean hasJoiningMembers = !new_mbrs.isEmpty();
    try {
        boolean successfulFlush = !useFlushIfPresent || !gms.flushProtocolInStack || gms.startFlush(new_view);
        if (!successfulFlush && hasJoiningMembers) {
            // Don't send a join response if the flush fails (http://jira.jboss.org/jira/browse/JGRP-759)
            // The joiner should block until the previous FLUSH completed
            // we still have to send potential leave responses
            sendLeaveResponses(leaving_mbrs);
            // but let the joining client timeout and send another join request
            return;
        }
        // of those messages if he misses them
        if (hasJoiningMembers) {
            gms.getDownProtocol().down(new Event(Event.SUSPEND_STABLE, MAX_SUSPEND_TIMEOUT));
            // create a new digest, which contains the new members, minus left members
            MutableDigest join_digest = new MutableDigest(new_view.getMembersRaw()).set(gms.getDigest());
            for (Address member : new_mbrs) // ... and set the new members. their first seqno will be 1
            join_digest.set(member, 0, 0);
            // incomplete, we don't send a JoinRsp back to the joiner(s). This shouldn't be a problem as they will retry
            if (join_digest.allSet() || join_digest.set(gms.getDigest()).allSet())
                join_rsp = new JoinRsp(new_view, join_digest);
            else
                log.warn("%s: digest does not match view (missing seqnos for %s); dropping JOIN-RSP", gms.local_addr, Arrays.toString(join_digest.getNonSetMembers()));
        }
        // no-op if no leaving members
        sendLeaveResponses(leaving_mbrs);
        // we don't need to send the digest to existing members: https://issues.jboss.org/browse/JGRP-1317
        gms.castViewChangeAndSendJoinRsps(new_view, null, new_view.getMembers(), new_mbrs, join_rsp);
    } finally {
        if (hasJoiningMembers)
            gms.getDownProtocol().down(new Event(Event.RESUME_STABLE));
        if (!joinAndStateTransferInitiated && useFlushIfPresent)
            gms.stopFlush();
        if (self_leaving)
            // in case connect() is called again
            gms.initState();
    }
}
Also used : Address(org.jgroups.Address) View(org.jgroups.View) Event(org.jgroups.Event)

Example 7 with View

use of org.jgroups.View in project JGroups by belaban.

the class DeliveryManagerImpl method getAndSetView.

@GuardedBy("deliverySet")
private View getAndSetView(View newView) {
    View oldView = currentView;
    currentView = newView;
    return oldView;
}
Also used : View(org.jgroups.View) GuardedBy(org.jgroups.annotations.GuardedBy)

Example 8 with View

use of org.jgroups.View in project JGroups by belaban.

the class GroupRequest method viewChange.

/**
 * Any member of 'membership' that is not in the new view is flagged as SUSPECTED. Any member in the new view that
 * is <em>not</em> in the membership (ie, the set of responses expected for the current RPC) will <em>not</em> be
 * added to it. If we did this we might run into the following problem:
 * <ul>
 * <li>Membership is {A,B}
 * <li>A sends a synchronous group RPC (which sleeps for 60 secs in the invocation handler)
 * <li>C joins while A waits for responses from A and B
 * <li>If this would generate a new view {A,B,C} and if this expanded the response set to {A,B,C}, A would wait
 * forever on C's response because C never received the request in the first place, therefore won't send a response.
 * </ul>
 */
public void viewChange(View view, boolean handle_previous_subgroups) {
    if (view == null || rsps == null || rsps.isEmpty())
        return;
    boolean changed = false;
    lock.lock();
    try {
        if (view instanceof MergeView && handle_previous_subgroups) {
            // unless that rsp has already been received (https://issues.redhat.com/browse/JGRP-2575)
            for (View v : ((MergeView) view).getSubgroups()) {
                if (!v.containsMember(corr.local_addr)) {
                    for (Address mbr : v.getMembersRaw()) if (setSuspected(mbr))
                        changed = true;
                }
            }
        }
        for (Map.Entry<Address, Rsp<T>> entry : rsps.entrySet()) {
            Address mbr = entry.getKey();
            // SiteAddresses are not checked as they might be in a different cluster
            if (!(mbr instanceof SiteAddress) && !view.containsMember(mbr)) {
                Rsp<T> rsp = entry.getValue();
                if (rsp.setSuspected()) {
                    if (!(rsp.wasReceived() || rsp.wasUnreachable()))
                        num_received++;
                    changed = true;
                }
            }
        }
        if (changed && responsesComplete()) {
            complete(this.rsps);
            corrDone();
        }
    } finally {
        lock.unlock();
    }
}
Also used : MergeView(org.jgroups.MergeView) SiteAddress(org.jgroups.protocols.relay.SiteAddress) SiteAddress(org.jgroups.protocols.relay.SiteAddress) Address(org.jgroups.Address) MergeView(org.jgroups.MergeView) View(org.jgroups.View) Map(java.util.Map) Rsp(org.jgroups.util.Rsp)

Example 9 with View

use of org.jgroups.View in project JGroups by belaban.

the class PDC method down.

public Object down(Event evt) {
    switch(evt.getType()) {
        case Event.GET_PHYSICAL_ADDRESS:
            Object addr = down_prot.down(evt);
            Address arg = evt.getArg();
            return addr != null ? addr : cache.get(arg);
        case Event.GET_PHYSICAL_ADDRESSES:
            Collection<PhysicalAddress> addrs = (Collection<PhysicalAddress>) down_prot.down(evt);
            Collection<PhysicalAddress> tmp = new HashSet<>(addrs);
            tmp.addAll(cache.values());
            return tmp;
        case Event.GET_LOGICAL_PHYSICAL_MAPPINGS:
            Map<Address, PhysicalAddress> map = (Map<Address, PhysicalAddress>) down_prot.down(evt);
            Map<Address, PhysicalAddress> new_map = new HashMap<>(map);
            new_map.putAll(cache);
            return new_map;
        case Event.ADD_PHYSICAL_ADDRESS:
            Tuple<Address, PhysicalAddress> new_val = evt.getArg();
            if (new_val != null) {
                cache.put(new_val.getVal1(), new_val.getVal2());
                writeNodeToDisk(new_val.getVal1(), new_val.getVal2());
            }
            break;
        case Event.REMOVE_ADDRESS:
            Address tmp_addr = evt.getArg();
            if (cache.remove(tmp_addr) != null)
                removeNodeFromDisk(tmp_addr);
            break;
        case Event.VIEW_CHANGE:
            List<Address> members = ((View) evt.getArg()).getMembers();
            cache.keySet().stream().filter(mbr -> !members.contains(mbr)).forEach(mbr -> {
                cache.remove(mbr);
                removeNodeFromDisk(mbr);
            });
            break;
    }
    return down_prot.down(evt);
}
Also used : Property(org.jgroups.annotations.Property) Protocol(org.jgroups.stack.Protocol) Event(org.jgroups.Event) UUID(org.jgroups.util.UUID) java.util(java.util) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) PhysicalAddress(org.jgroups.PhysicalAddress) org.jgroups.util(org.jgroups.util) java.io(java.io) ManagedOperation(org.jgroups.annotations.ManagedOperation) MBean(org.jgroups.annotations.MBean) Address(org.jgroups.Address) FileChannel(java.nio.channels.FileChannel) View(org.jgroups.View) PhysicalAddress(org.jgroups.PhysicalAddress) Address(org.jgroups.Address) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) PhysicalAddress(org.jgroups.PhysicalAddress) View(org.jgroups.View) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 10 with View

use of org.jgroups.View in project JGroups by belaban.

the class DISCARD method down.

public Object down(Event evt) {
    switch(evt.getType()) {
        case Event.VIEW_CHANGE:
            View view = evt.getArg();
            List<Address> mbrs = view.getMembers();
            members.clear();
            members.addAll(mbrs);
            if (discard_dialog != null)
                discard_dialog.handleView(mbrs);
            break;
        case Event.GET_PING_DATA:
            if (discard_all)
                return null;
            break;
    }
    return down_prot.down(evt);
}
Also used : Address(org.jgroups.Address) View(org.jgroups.View)

Aggregations

View (org.jgroups.View)51 Address (org.jgroups.Address)24 JChannel (org.jgroups.JChannel)14 GMS (org.jgroups.protocols.pbcast.GMS)6 Event (org.jgroups.Event)5 Receiver (org.jgroups.Receiver)5 ArrayList (java.util.ArrayList)3 Map (java.util.Map)3 ViewId (org.jgroups.ViewId)3 IOException (java.io.IOException)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 ConcurrentMap (java.util.concurrent.ConcurrentMap)2 NetView (org.apache.geode.distributed.internal.membership.NetView)2 IpAddress (org.jgroups.stack.IpAddress)2 UUID (org.jgroups.util.UUID)2 java.io (java.io)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 DataInputStream (java.io.DataInputStream)1 FileOutputStream (java.io.FileOutputStream)1 InputStream (java.io.InputStream)1