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

org.jgroups.blocks.AbstractConnectionMap Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote Jakarta Enterprise Beans and Jakarta Messaging, including all dependencies. It is intended for use by those not using maven, maven users should just import the Jakarta Enterprise Beans and Jakarta Messaging 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: 35.0.0.Beta1
Show newest version
package org.jgroups.blocks;

import org.jgroups.Address;
import org.jgroups.Global;
import org.jgroups.util.ThreadFactory;
import org.jgroups.util.Util;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public abstract class AbstractConnectionMap implements ConnectionMap {
        
    protected final List> conn_listeners=new ArrayList<>();
    protected final Map                 conns=new HashMap<>();
    protected final Lock                           lock = new ReentrantLock(); // syncs conns
    protected final Lock                           sock_creation_lock= new ReentrantLock(true); // syncs socket establishment
    protected final ThreadFactory                  factory;
    protected final long                           reaperInterval;
    protected final Reaper                         reaper;

    public AbstractConnectionMap(ThreadFactory factory) {
        this(factory,0);        
    }
    
    public AbstractConnectionMap(ThreadFactory factory,long reaperInterval) {
        super();
        this.factory=factory;        
        this.reaperInterval=reaperInterval;
        reaper=reaperInterval > 0?  new Reaper() : null;
    }
    
    public Lock getLock(){
        return lock;
    }
    

    public boolean hasConnection(Address address) {
        return conns.containsKey(address);
    }

    public void addConnection(Address address, V conn) {
        V previous = conns.put(address, conn);
        Util.close(previous); // closes previous connection (if present)
        notifyConnectionOpened(address, conn);
    }

    public void addConnectionMapListener(ConnectionMapListener cml) {
        if(cml != null && !conn_listeners.contains(cml))
            conn_listeners.add(cml);
    } 
    
    public int getNumConnections() {
        lock.lock();
        try {
            return conns.size();
        }
        finally {
            lock.unlock();
        }
    }

    public int getNumOpenConnections() {
        int retval=0;
        lock.lock();
        try {
            for(Connection conn: conns.values())
                if(conn.isOpen())
                    retval++;
            return retval;
        }
        finally {
            lock.unlock();
        }
    }

    public String printConnections() {
        StringBuilder sb=new StringBuilder();

        lock.lock();
        try {
            for(Map.Entry entry: conns.entrySet()) {
                sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
            }
        }
        finally {
            lock.unlock();
        }

        return sb.toString();
    }

    public ThreadFactory getThreadFactory() {
        return factory;
    }


    /** Only removes the connection if conns.get(address) == conn */
    public void removeConnectionIfPresent(Address address, V conn) {
        if(address == null || conn == null)
            return;

        lock.lock();
        try {
            V existing=conns.get(address);
            if(conn == existing) {
                V tmp=conns.remove(address);
                Util.close(tmp);
            }
        }
        finally {
            lock.unlock();
        }
    }

    public void removeConnectionMapListener(ConnectionMapListener cml) {
        if(cml != null)
            conn_listeners.remove(cml);
    }

    /**
     * Removes all connections which are not in current_mbrs
     * 
     * @param current_mbrs
     */
    public void retainAll(Collection
current_mbrs) { if(current_mbrs == null) return; Map copy=null; lock.lock(); try { copy=new HashMap<>(conns); conns.keySet().retainAll(current_mbrs); } finally { lock.unlock(); } copy.keySet().removeAll(current_mbrs); for(Iterator> i = copy.entrySet().iterator();i.hasNext();) { Entry e = i.next(); Util.close(e.getValue()); } copy.clear(); } public void start() throws Exception { if(reaper != null) { reaper.start(); } } public void stop() { if(reaper != null) reaper.stop(); lock.lock(); try { for(Iterator> i = conns.entrySet().iterator();i.hasNext();) { Entry e = i.next(); Util.close(e.getValue()); } clear(); } finally { lock.unlock(); } conn_listeners.clear(); } protected void clear() { lock.lock(); try { conns.clear(); } finally { lock.unlock(); } } protected void notifyConnectionClosed(Address address) { for(ConnectionMapListener l:conn_listeners) { l.connectionClosed(address); } } protected void notifyConnectionOpened(Address address, V conn) { for(ConnectionMapListener l:conn_listeners) l.connectionOpened(address, conn); } class Reaper implements Runnable { private Thread thread; public synchronized void start() { if(thread == null || !thread.isAlive()) { thread=factory.newThread(new Reaper(), "Reaper"); thread.start(); } } public synchronized void stop() { if(thread != null && thread.isAlive()) { thread.interrupt(); try { thread.join(Global.THREAD_SHUTDOWN_WAIT_TIME); } catch(InterruptedException ignored) { } } thread=null; } public void run() { while(!Thread.currentThread().isInterrupted()) { lock.lock(); try { for(Iterator> it=conns.entrySet().iterator();it.hasNext();) { Entry entry=it.next(); V c=entry.getValue(); if(c.isExpired(System.nanoTime())) { Util.close(c); it.remove(); } } } finally { lock.unlock(); } Util.sleep(reaperInterval); } } } public interface ConnectionMapListener { public void connectionClosed(Address address); public void connectionOpened(Address address, V conn); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy