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

org.jgroups.protocols.SHARED_LOOPBACK 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).

There is a newer version: 33.0.2.Final
Show newest version
package org.jgroups.protocols;

import org.jgroups.Address;
import org.jgroups.Event;
import org.jgroups.PhysicalAddress;
import org.jgroups.View;
import org.jgroups.annotations.ManagedAttribute;
import org.jgroups.annotations.ManagedOperation;
import org.jgroups.util.AsciiString;
import org.jgroups.util.UUID;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;


/**
 * Loopback transport shared by all channels within the same VM. Property for testing is that no messages are lost. Allows
 * us to test various protocols (with ProtocolTester) at maximum speed.
 * @author Bela Ban
 */
public class SHARED_LOOPBACK extends TP {
    protected PhysicalAddress  physical_addr;

    @ManagedAttribute(description="The current view",writable=false)
    protected volatile View    view;

    protected volatile boolean is_server=false, is_coord=false;

    /** Map of cluster names and address-protocol mappings. Used for routing messages to all or single members */
    private static final ConcurrentMap> routing_table=new ConcurrentHashMap<>();


    public boolean supportsMulticasting() {
        return true; // kind of...
    }

    public View    getView()  {return view;}
    public boolean isServer() {return is_server;}
    public boolean isCoord()  {return is_coord;}

    public String toString() {
        return "SHARED_LOOPBACK(local address: " + local_addr + ')';
    }

    @ManagedOperation(description="Dumps the contents of the routing table")
    public static String dumpRoutingTable() {
        StringBuilder sb=new StringBuilder();
        for(Map.Entry> entry: routing_table.entrySet()) {
            AsciiString cluster_name=entry.getKey();
            Set
mbrs=entry.getValue().keySet(); sb.append(cluster_name).append(": ").append(mbrs).append("\n"); } return sb.toString(); } public void sendMulticast(AsciiString cluster_name, byte[] data, int offset, int length) throws Exception { Map dests=routing_table.get(this.cluster_name); if(dests == null) { if(log.isTraceEnabled()) log.trace("no destination found for " + this.cluster_name); return; } for(Map.Entry entry: dests.entrySet()) { Address dest=entry.getKey(); SHARED_LOOPBACK target=entry.getValue(); if(local_addr != null && local_addr.equals(dest)) continue; // message was already looped back try { target.receive(local_addr, data, offset, length, true); } catch(Throwable t) { log.error("failed sending message to " + dest, t); } } } public void sendUnicast(PhysicalAddress dest, byte[] data, int offset, int length) throws Exception { sendToSingleMember(dest, data, offset, length); } protected void sendToSingleMember(Address dest, byte[] buf, int offset, int length) throws Exception { Map dests=routing_table.get(cluster_name); if(dests == null) { log.trace("no destination found for " + cluster_name); return; } SHARED_LOOPBACK target=dests.get(dest); if(target == null) { log.trace("destination address " + dest + " not found"); return; } target.receive(local_addr, buf, offset, length, true); } public static List getDiscoveryResponsesFor(String cluster_name) { if(cluster_name == null) return null; Map mbrs=routing_table.get(new AsciiString(cluster_name)); List rsps=new ArrayList<>(mbrs != null? mbrs.size() : 0); if(mbrs != null) { for(Map.Entry entry: mbrs.entrySet()) { Address addr=entry.getKey(); SHARED_LOOPBACK slp=entry.getValue(); PingData data=new PingData(addr, slp.isServer(), UUID.get(addr), null).coord(slp.isCoord()); rsps.add(data); } } return rsps; } public String getInfo() { return toString(); } protected PhysicalAddress getPhysicalAddress() { return physical_addr; } /*------------------------------ Protocol interface ------------------------------ */ public Object down(Event evt) { Object retval=super.down(evt); switch(evt.getType()) { case Event.CONNECT: case Event.CONNECT_WITH_STATE_TRANSFER: case Event.CONNECT_USE_FLUSH: case Event.CONNECT_WITH_STATE_TRANSFER_USE_FLUSH: register(cluster_name, local_addr, this); break; case Event.SET_LOCAL_ADDRESS: local_addr=(Address)evt.getArg(); break; case Event.BECOME_SERVER: // called after client has joined and is fully working group member is_server=true; break; case Event.VIEW_CHANGE: case Event.TMP_VIEW: view=(View)evt.getArg(); Address[] mbrs=((View)evt.getArg()).getMembersRaw(); is_coord=local_addr != null && mbrs != null && mbrs.length > 0 && local_addr.equals(mbrs[0]); break; case Event.GET_PING_DATA: return getDiscoveryResponsesFor((String)evt.getArg()); // don't pass further down } return retval; } public void stop() { super.stop(); is_server=is_coord=false; unregister(cluster_name, local_addr); } public void destroy() { super.destroy(); // We cannot clear the routing table, as it is shared between channels, and so we would clear the routing for // a different channel, too ! unregister(cluster_name, local_addr); } protected static void register(AsciiString channel_name, Address local_addr, SHARED_LOOPBACK shared_loopback) { Map map=routing_table.get(channel_name); if(map == null) { map=new ConcurrentHashMap<>(); Map tmp=routing_table.putIfAbsent(channel_name,map); if(tmp != null) map=tmp; } map.put(local_addr, shared_loopback); } protected static void unregister(AsciiString channel_name, Address local_addr) { Map map=channel_name != null? routing_table.get(channel_name) : null; if(map != null) { map.remove(local_addr); if(map.isEmpty()) routing_table.remove(channel_name); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy