package com.yahoo.dtf.rendezvous;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import com.yahoo.dtf.DTFNode;
import com.yahoo.dtf.actions.Action;
import com.yahoo.dtf.actions.protocol.CleanUpHook;
import com.yahoo.dtf.actions.protocol.Lock;
import com.yahoo.dtf.actions.rendezvous.RendezvousOperation;
import com.yahoo.dtf.actions.rendezvous.Rendezvous_destroy;
import com.yahoo.dtf.comm.Comm;
import com.yahoo.dtf.components.ComponentHook;
import com.yahoo.dtf.components.Components;
import com.yahoo.dtf.exception.DTFException;
public class RendezvousComponentHook implements ComponentHook,
CleanUpHook {
private static Object _rplock = new Object();
public ArrayList<Action> handleComponent(String id) throws DTFException {
synchronized (_rplock) {
ArrayList<Action> result = new ArrayList<Action>();
HashMap<String, RendezvousPoint> rps =
RendezvousOperation.getRendezvousPoints();
synchronized (rps) {
ArrayList<String> sent = getSentRendezvous(id);
Iterator<Entry<String,RendezvousPoint>> entries =
rps.entrySet().iterator();
ArrayList<String> addme = new ArrayList<String>();
while ( entries.hasNext() ) {
Entry<String,RendezvousPoint> entry = entries.next();
String key = entry.getKey();
if ( !sent.contains(key) ) {
RendezvousPoint rp = entry.getValue();
RendezvousCreate rc = new RendezvousCreate();
if (Action.getLogger().isDebugEnabled()) {
Action.getLogger().debug("Sending [" + rp.getId() +
"] to [" + id + "]");
}
rc.setId(rp.getId());
rc.setParties(""+rp.getParties());
rc.setCid(Action.getLocalID());
result.add(rc);
addme.add(rp.getId());
}
}
sent.addAll(addme);
return result;
}
}
}
public static synchronized void createOnAll(String id,
int parties,
String cid)
throws DTFException {
synchronized (_rplock) {
Components components = Action.getComponents();
Comm comm = Action.getComm();
if (components == null)
return;
Iterator<String> cids = components._elems.keySet().iterator();
while (cids.hasNext()) {
String component = cids.next();
ArrayList<String> sent = getSentRendezvous(component);
if ( !sent.contains(id) ) {
Lock lock = components.getComponent(component);
if (Action.getLogger().isDebugEnabled()) {
Action.getLogger().debug("Sending [" + id + "] to ["
+ component + "]");
}
RendezvousCreate rc = new RendezvousCreate();
rc.setId(id);
rc.setParties("" + parties);
rc.setCid(cid);
comm.sendAction(lock.getId(), rc).execute();
// every component has to be labeled as owning this rendezvous
// point now
sent.add(id);
}
}
}
}
public static synchronized void removeRendezvous(String id)
throws DTFException {
if ( !DTFNode.getType().equals("dtfx") )
return;
synchronized (_rplock) {
Components components = Action.getComponents();
Comm comm = Action.getComm();
Iterator<String> cids = components._elems.keySet().iterator();
while ( cids.hasNext() ) {
String cid = cids.next();
ArrayList<String> sent = getSentRendezvous(cid);
if ( sent.contains(id) ) {
Lock lock = components.getComponent(cid);
Rendezvous_destroy rd = new Rendezvous_destroy();
rd.setId(id);
comm.sendAction(lock.getId(), rd).execute();
sent.remove(id);
}
}
}
}
public void cleanup() throws DTFException {
RendezvousOperation.cleanUp();
}
/*
* Keep track of the sent rendezvous points per component
*/
private static Object _mapLock = new Object();
private static ArrayList<String> getSentRendezvous(String id) {
synchronized(_mapLock) {
HashMap<String,ArrayList<String>> map =
(HashMap<String,ArrayList<String>>)
Action.getGlobalContext("getrendezvouspoints." + id);
if (map == null) {
map = new HashMap<String, ArrayList<String>>();
Action.registerGlobalContext("getrendezvouspoints." + id, map);
}
ArrayList<String> sent = map.get(id);
if ( sent == null) {
sent = new ArrayList<String>();
map.put(id,sent);
}
return sent;
}
}
}