PageRenderTime 25ms CodeModel.GetById 17ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2dist041108/src/edu/vub/at/actors/net/ConnectionListenerManager.java

http://ambienttalk.googlecode.com/
Java | 175 lines | 89 code | 12 blank | 74 comment | 29 complexity | a63a093438d10d8958dc9bcd0553f668 MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * MembershipNotifier.java created on Feb 16, 2007 at 1:14:08 PM
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.at.actors.net;
 29
 30import edu.vub.at.actors.id.ATObjectID;
 31import edu.vub.at.actors.id.VirtualMachineID;
 32import edu.vub.at.actors.natives.NATFarReference;
 33import edu.vub.at.util.logging.Logging;
 34import edu.vub.util.MultiMap;
 35
 36import java.lang.ref.WeakReference;
 37import java.util.Iterator;
 38import java.util.Set;
 39
 40/**
 41 * An instance of this class manages disconnection and reconnection subscriptions and
 42 * notifications for far references. Whenever virtual machines connect or
 43 * disconnect from the multicast group, this object is notified. Its role is to propagate
 44 * these notifications to all registered ConnectionListeners, which will usually be remote
 45 * references pointing to objects hosted by the connecting/disconnecting VM.
 46 *
 47 * @author tvcutsem
 48 */
 49public class ConnectionListenerManager {
 50	
 51	/**
 52	 * A collection of ConnectionListeners which are interested in the (dis)appearance of a single
 53	 * node in the overlay network.
 54	 */
 55	private final MultiMap connectionListeners_;
 56	
 57	/**
 58	 * Creates a new manager on which ConnectionListeners monitoring the (dis)appearance
 59	 * of a single address can register to.
 60	 */
 61	public ConnectionListenerManager() {
 62		connectionListeners_ = new MultiMap();
 63	}
 64	
 65	/**
 66	 * Registers <code>listener</code> to be notified whenever a virtual machine becomes (un)reachable.
 67	 * 
 68	 * @param virtualMachine - an address of the virtual machine hosting the object the listener is interested in
 69	 * @param listener - a listener which will be notified whenever the said address connects or disconnects
 70	 */
 71	public synchronized void addConnectionListener(VirtualMachineID virtualMachine, ConnectionListener listener) {
 72		connectionListeners_.put(virtualMachine, new WeakReference(listener));
 73	}
 74	
 75	/**
 76	 * Unregisters <code>listener</code> such that it will no longer be notified whenever a 
 77	 * particular virtual machine becomes (un)reachable.
 78	 */
 79	public synchronized void removeConnectionListener(VirtualMachineID virtualMachine, ConnectionListener listener) {
 80
 81		Set listeners = (Set)connectionListeners_.get(virtualMachine);
 82		if(listeners != null) {
 83			for (Iterator i = listeners.iterator(); i.hasNext();) {
 84				WeakReference pooled = (WeakReference) i.next();
 85				if (pooled != null) {
 86					ConnectionListener list = (ConnectionListener) pooled.get();
 87					if( list != null){
 88						if (list.equals(listener)) {
 89							Logging.VirtualMachine_LOG.info("Removing ELFarReference from CLM " + this);
 90							i.remove();
 91						}
 92					}else{
 93						// the listener referenced by the WeakReference was already gced => remove the pointer to WeakReference.
 94						i.remove();
 95					}
 96				}
 97			}
 98		}
 99	}
100
101	/**
102	 * Notify all connection listeners for the given VM id that that VM has come online
103	 */
104	public synchronized void notifyConnected(VirtualMachineID vmId) {
105		//notify all connectionlisteners for this member
106		Set listeners = (Set)connectionListeners_.get(vmId);
107		if (listeners != null) {
108			for (Iterator i = listeners.iterator(); i.hasNext();) {
109				WeakReference pooled = (WeakReference) i.next();
110				if (pooled != null) {
111					ConnectionListener listener = (ConnectionListener) pooled.get();
112					if (listener != null){
113						listener.connected();
114					}else{
115						// the listener referenced by the WeakReference was already gced => remove the pointer to WeakReference.
116						i.remove();
117					}
118				}
119			}
120		}
121	}
122	
123	/**
124	 * Notify all connection listeners for the given VM id that that VM has gone offline
125	 */
126	public synchronized void notifyDisconnected(VirtualMachineID vmId){
127		//notify all connectionlisteners for this member
128		Set listeners = (Set)connectionListeners_.get(vmId);
129		if (listeners != null) {
130			for (Iterator i = listeners.iterator(); i.hasNext();) {
131				WeakReference pooled = (WeakReference) i.next();
132				if (pooled != null) {
133					ConnectionListener listener = (ConnectionListener) pooled.get();
134					if (listener != null){
135						listener.disconnected();
136					}else{
137						// the listener referenced by the WeakReference was already gced => remove the pointer to WeakReference.
138						i.remove();
139					}
140				}
141			}
142		}
143	}
144	
145	/**
146	 * Notify all connection listeners registered on the given remote object
147	 */
148	public synchronized void notifyObjectTakenOffline(ATObjectID objId){
149		//notify only the connectionlisteners for this objId
150		Set listeners = (Set)connectionListeners_.get(objId.getVirtualMachineId());
151		if (listeners != null) {
152			for (Iterator i = listeners.iterator(); i.hasNext();) {
153				WeakReference pooled = (WeakReference) i.next();
154				if (pooled != null) {
155					ConnectionListener listener = (ConnectionListener) pooled.get();
156					if (listener instanceof NATFarReference) {
157						ATObjectID destination = ((NATFarReference)listener).getObjectId();
158						if (destination.equals(objId)){
159							listener.takenOffline();
160							//The entry on the table is removed so that the remote far reference is never 
161							//notified when the vmid hosting the offline object becomes (un)reachable.
162							//In fact, the reference doesn't care about the such notifications because 
163							//an offline object will never become online.
164							i.remove();
165						}
166					}else{
167						// the listener referenced by the WeakReference was already gced => remove the pointer to WeakReference.
168						i.remove();
169					}
170				}	
171			}
172		}
173	}
174	
175}