package com.robonobo.mina.instance;
import java.util.*;
import com.robonobo.common.concurrent.CatchingRunnable;
import com.robonobo.mina.network.BCPair;
import com.robonobo.mina.network.LCPair;
public class FlowRateMgr {
MinaInstance mina;
Map<String, Integer> bMap = Collections.synchronizedMap(new HashMap<String, Integer>());
Map<String, Integer> lMap = Collections.synchronizedMap(new HashMap<String, Integer>());
long lastFRUpdate = 0;
public FlowRateMgr(MinaInstance mina) {
this.mina = mina;
}
/**
* Bytes/sec
*/
public int getBroadcastingFlowRate(String sid) {
checkAndUpdateFlowRates();
Integer result = bMap.get(sid);
if(result == null)
return 0;
return result;
}
/**
* Bytes/sec
*/
public int getListeningFlowRate(String sid) {
checkAndUpdateFlowRates();
Integer result = lMap.get(sid);
if(result == null)
return 0;
return result;
}
private void checkAndUpdateFlowRates() {
// If it's been more than a second, fire off a thread to update the flow rate
// Avoids repeated iteration over connections, and nary a synch block in sight
// This means this flowrate data will be out of date, but this shouldn't matter
long now = System.currentTimeMillis();
if((now - lastFRUpdate) > 1000l) {
lastFRUpdate = now;
mina.getExecutor().execute(new CatchingRunnable() {
public void doRun() throws Exception {
Set<String> liveSids = new HashSet<String>(Arrays.asList(mina.getStreamMgr().getLiveStreamIds()));
// Add any sids we currently have values for, to make sure they're removed if they're now 0
liveSids.addAll(bMap.keySet());
liveSids.addAll(lMap.keySet());
for (String sid : liveSids) {
int bfr = 0;
BCPair[] bcps = mina.getSCM().getBroadcastConns(sid);
for (int i = 0; i < bcps.length; i++) {
bfr += bcps[i].getFlowRate();
}
if(bfr == 0)
bMap.remove(sid);
else
bMap.put(sid, bfr);
int lfr = 0;
LCPair[] lcps = mina.getSCM().getListenConns(sid);
for (int i = 0; i < lcps.length; i++) {
lfr += lcps[i].getFlowRate();
}
if(lfr == 0)
lMap.remove(sid);
else
lMap.put(sid, lfr);
}
}
});
}
}
}