/*
* Quasar: lightweight threads and actors for the JVM.
* Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
package co.paralleluniverse.fibers;
import co.paralleluniverse.common.monitoring.Metrics;
import co.paralleluniverse.strands.Strand;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import static com.codahale.metrics.MetricRegistry.name;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author pron
*/
class MetricsFibersMonitor implements FibersMonitor {
private final Counter activeCount;
//private final Counter runnableCount;
private final Counter waitingCount;
private final Meter spuriousWakeups;
private final Histogram timedParkLatency;
private final Gauge<Map<String, String>> runawayFibers;
private Map<Fiber, StackTraceElement[]> problemFibers;
public MetricsFibersMonitor(String name, FiberScheduler scheduler) {
this.activeCount = Metrics.counter(metric(name, "numActiveFibers"));
this.waitingCount = Metrics.counter(metric(name, "numWaitingFibers"));
this.spuriousWakeups = Metrics.meter(metric(name, "spuriousWakeups"));
this.timedParkLatency = Metrics.histogram(metric(name, "timedParkLatency"));
this.runawayFibers = new Gauge<Map<String, String>>() {
@Override
public Map<String, String> getValue() {
Map<String, String> map = new HashMap<>();
if (problemFibers != null) {
for (Map.Entry<Fiber, StackTraceElement[]> e : problemFibers.entrySet())
map.put(e.getKey().toString(), Strand.toString(e.getValue()));
}
return map;
}
};
Metrics.register("runawayFibers", runawayFibers);
}
protected final String metric(String poolName, String name) {
return name("co.paralleluniverse", "fibers", poolName, name);
}
@Override
public void unregister() {
}
@Override
public void fiberStarted(Fiber fiber) {
activeCount.inc();
}
@Override
public void fiberTerminated(Fiber fiber) {
activeCount.dec();
//runnableCount.dec();
}
@Override
public void fiberSuspended() {
//runnableCount.dec();
waitingCount.inc();
}
@Override
public void fiberResumed() {
//runnableCount.inc();
waitingCount.dec();
}
@Override
public void spuriousWakeup() {
spuriousWakeups.mark();
}
@Override
public void timedParkLatency(long ns) {
timedParkLatency.update(ns);
}
@Override
public void setRunawayFibers(Collection<Fiber> fs) {
if (fs == null || fs.isEmpty())
this.problemFibers = null;
else {
this.problemFibers = new HashMap<>();
for (Fiber f : fs)
problemFibers.put(f, f.getStackTrace());
}
}
}