Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jgroups.util.RpcStats Maven / Gradle / Ivy
package org.jgroups.util;
import org.jgroups.Address;
import org.jgroups.Global;
import org.jgroups.protocols.RTTHeader;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
/**
* Keeps track of stats for sync and async unicasts and multicasts
* @author Bela Ban
* @since 3.6.8
*/
public class RpcStats {
protected final AtomicInteger sync_unicasts=new AtomicInteger(0);
protected final AtomicInteger async_unicasts=new AtomicInteger(0);
protected final AtomicInteger sync_multicasts=new AtomicInteger(0);
protected final AtomicInteger async_multicasts=new AtomicInteger(0);
protected final AtomicInteger sync_anycasts=new AtomicInteger(0);
protected final AtomicInteger async_anycasts=new AtomicInteger(0);
protected volatile Map stats;
protected volatile Map rtt_stats;
public enum Type {MULTICAST, UNICAST, ANYCAST}
public RpcStats(boolean extended_stats) {
extendedStats(extended_stats);
}
public int unicasts(boolean sync) {return sync? sync_unicasts.get() : async_unicasts.get();}
public int multicasts(boolean sync) {return sync? sync_multicasts.get() : async_multicasts.get();}
public int anycasts(boolean sync) {return sync? sync_anycasts.get() : async_anycasts.get();}
public boolean extendedStats() {return stats != null;}
public RpcStats extendedStats(boolean f) {
if(f) {
if(stats == null)
stats=new ConcurrentHashMap<>();
}
else
stats=null;
return this;
}
public void reset() {
if(stats != null)
stats.clear();
if(rtt_stats != null)
rtt_stats.clear();
for(AtomicInteger ai: Arrays.asList(sync_unicasts, async_unicasts, sync_multicasts, async_multicasts, sync_anycasts, async_anycasts))
ai.set(0);
}
public void add(Type type, Address dest, boolean sync, long time) {
update(type, sync);
addToResults(dest, sync, time);
}
public void addAnycast(boolean sync, long time, Collection dests) {
update(Type.ANYCAST, sync);
if(dests != null)
for(Address dest: dests)
addToResults(dest, sync, time);
}
public void addRTTStats(Address sender, RTTHeader hdr) {
if(hdr == null)
return;
if(this.rtt_stats == null)
this.rtt_stats=new ConcurrentHashMap<>();
Address key=sender == null? Global.NULL_ADDRESS : sender;
RTTStat rtt_stat=rtt_stats.computeIfAbsent(key, k -> new RTTStat());
rtt_stat.add(hdr);
}
public void retainAll(Collection members) {
Map map;
if(members == null || (map=stats) == null)
return;
map.keySet().retainAll(members);
if(rtt_stats != null)
rtt_stats.keySet().retainAll(members);
}
public String printStatsByDest() {
if(stats == null) return "(no stats)";
StringBuilder sb=new StringBuilder("\n");
for(Map.Entry entry: stats.entrySet()) {
Address dst=entry.getKey();
sb.append(String.format("%s: %s\n", dst == Global.NULL_ADDRESS? "" : dst, entry.getValue()));
}
return sb.toString();
}
public String printRTTStatsByDest() {
if(rtt_stats == null) return "(no RTT stats)";
StringBuilder sb=new StringBuilder("\n");
for(Map.Entry entry: rtt_stats.entrySet()) {
Address dst=entry.getKey();
sb.append(String.format("%s:\n%s\n", dst == Global.NULL_ADDRESS? "" : dst, entry.getValue()));
}
return sb.toString();
}
public String toString() {
return String.format("sync mcasts: %d, async mcasts: %d, sync ucasts: %d, async ucasts: %d, sync acasts: %d, async acasts: %d",
sync_multicasts.get(), async_multicasts.get(), sync_unicasts.get(), async_unicasts.get(),
sync_anycasts.get(), async_anycasts.get());
}
protected void update(Type type, boolean sync) {
switch(type) {
case MULTICAST:
if(sync)
sync_multicasts.incrementAndGet();
else
async_multicasts.incrementAndGet();
break;
case UNICAST:
if(sync)
sync_unicasts.incrementAndGet();
else
async_unicasts.incrementAndGet();
break;
case ANYCAST:
if(sync)
sync_anycasts.incrementAndGet();
else
async_anycasts.incrementAndGet();
break;
}
}
protected void addToResults(Address dest, boolean sync, long time) {
Map map=stats;
if(map == null)
return;
if(dest == null)
dest=Global.NULL_ADDRESS;
Result res=map.computeIfAbsent(dest, k -> new Result());
res.add(sync, time);
}
protected static class Result {
protected long sync, async;
protected final AverageMinMax avg=new AverageMinMax();
protected long sync() {return sync;}
protected long async() {return async;}
protected long min() {return avg.min();}
protected long max() {return avg.max();}
protected synchronized double avg() {return avg.average();}
protected synchronized void add(boolean sync, long time) {
if(sync)
this.sync++;
else
this.async++;
if(time > 0)
avg.add(time);
}
public String toString() {
double avg_us=avg()/1000.0; // convert nanos to microsecs
double min_us=avg.min()/1000.0; // us
double max_us=avg.max()/1000.0; // us
return String.format("async: %d, sync: %d, round-trip min/avg/max (us): %.2f / %.2f / %.2f", async, sync, min_us, avg_us, max_us);
}
}
protected static class RTTStat {
protected final AverageMinMax total_time=new AverageMinMax(); // RTT for a sync request
protected final AverageMinMax down_req_time=new AverageMinMax(); // send until the req is serialized
protected final AverageMinMax network_req_time=new AverageMinMax(); // serialization of req until deserialization
protected final AverageMinMax network_rsp_time=new AverageMinMax(); // serialization of rsp until deserialization
protected final AverageMinMax req_up_time=new AverageMinMax(); // deserialization of req until dispatching to app
protected final AverageMinMax rsp_up_time=new AverageMinMax(); // deserialization of rsp until after dispatching to app
protected final AverageMinMax processing_time=new AverageMinMax(); // time between reception of req and sending of rsp
protected void add(RTTHeader hdr) {
if(hdr == null)
return;
long tmp;
if((tmp=hdr.totalTime()) > 0)
total_time.add(tmp);
if((tmp=hdr.downRequest()) > 0)
down_req_time.add(tmp);
if((tmp=hdr.networkRequest()) > 0)
network_req_time.add(tmp);
if((tmp=hdr.networkResponse()) > 0)
network_rsp_time.add(tmp);
if((tmp=hdr.upReq()) > 0)
req_up_time.add(tmp);
if((tmp=hdr.processingTime()) > 0)
processing_time.add(tmp);
if((tmp=hdr.upRsp()) > 0)
rsp_up_time.add(tmp);
}
public String toString() {
return String.format(" total: %s\n down-req: %s\n network req: %s\n network rsp: %s\n" +
" up-req: %s\n up-rsp: %s\n processing time: %s\n",
total_time.toString(NANOSECONDS),
down_req_time.toString(NANOSECONDS),
network_req_time.toString(NANOSECONDS), network_rsp_time.toString(NANOSECONDS),
req_up_time.toString(NANOSECONDS), rsp_up_time.toString(NANOSECONDS),
processing_time.toString(NANOSECONDS));
}
}
}