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

org.jgroups.protocols.pbcast.Leaver Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

The newest version!
package org.jgroups.protocols.pbcast;

import org.jgroups.Address;
import org.jgroups.EmptyMessage;
import org.jgroups.Message;
import org.jgroups.logging.Log;
import org.jgroups.util.Promise;

import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Handles the leaving of a member from a group. On leave(), a LEAVE-REQ is sent to the coordinator and the caller is
 * blocked until a LEAVE-RSP has been received.
* If the coordinator changes before the response has been received, the LEAVE-REQ will be resent to the new * cordinator. If the coordinator is null, leave() returns. * * @author Bela Ban * @since 4.1.4 */ public class Leaver { protected final GMS gms; // gms.local_mbr is the address of the member which is leaving protected final Log log; protected final Promise
leave_promise=new Promise<>(); protected final AtomicBoolean leaving=new AtomicBoolean(false); public Leaver(GMS gms) { this.gms=Objects.requireNonNull(gms); log=gms.getLog(); } /** * Sends a LEAVE-REQ to the coordinator. Blocks the caller until a LEAVE-RSP has been received, or no coord is found. */ public void leave() { Address coord, me=gms.getAddress(); if(!leaving.compareAndSet(false, true)) { coord=gms.getCoord(); if(coord == null) { log.trace("%s: last member in the group (coord); leaving now", me); leave_promise.setResult(me); } else { log.trace("%s: re-sending LEAVE request to %s", me, coord); sendLeaveRequest(coord, me); } return; } try { leave_promise.reset(false); coord=gms.getCoord(); if(coord == null) { log.trace("%s: last member in the group (coord); leaving now", me); return; } log.trace("%s: sending LEAVE request to %s", me, coord); long start=System.currentTimeMillis(); sendLeaveRequest(coord, me); if(leaving.get()) { Address sender=leave_promise.getResult(gms.leave_timeout); long time=System.currentTimeMillis() - start; if(leave_promise.hasResult()) { if(sender != null) { boolean myself=Objects.equals(sender, me); log.trace("%s: got LEAVE response from %s in %d ms", me, myself? " self" : sender, time); } else log.trace("%s: timed out waiting for LEAVE response from %s (after %d ms)", me, coord, time); } } } finally { reset(); } } public void handleLeaveResponse(Address sender) { leave_promise.setResult(Objects.requireNonNull(sender)); } /** * Callback to notify Leaver that the coord changed. This will result in resending the LEAVE-REQ to the new * coordinator. If there's no new coord (e.g. because we're the last member), * {@link #leave()} (if there is one in progress) will return and unblock the caller. */ public void coordChanged(Address new_coord) { if(!leaving.get() || new_coord == null) return; Address leaving_mbr=gms.getAddress(); if(leaving_mbr == null) { log.error("local address is null, cannot re-send LEAVE request"); } else { log.trace("%s: re-sending LEAVE request to %s", gms.getAddress(), new_coord); sendLeaveRequest(new_coord, leaving_mbr); } } /** * Interrupts and stops the current leave process (if one is in progress). No-op is no leave process is in progress. * This unblocks the caller of {@link #leave()} (if present). */ public void reset() { if(leaving.compareAndSet(true, false)) leave_promise.setResult(null); } protected void sendLeaveRequest(Address coord, Address leaving_mbr) { Message msg=new EmptyMessage(coord).setFlag(Message.Flag.OOB) .putHeader(gms.getId(), new GMS.GmsHeader(GMS.GmsHeader.LEAVE_REQ, leaving_mbr)); gms.getDownProtocol().down(msg); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy