co.paralleluniverse.actors.JMXActorsMonitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of quasar-actors Show documentation
Show all versions of quasar-actors Show documentation
Fibers, Channels and Actors for the JVM
/*
* Quasar: lightweight threads and actors for the JVM.
* Copyright (C) 2013, 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.actors;
import co.paralleluniverse.common.monitoring.Counter;
import co.paralleluniverse.common.monitoring.MonitoringServices;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import jsr166e.LongAdder;
import org.cliffc.high_scale_lib.NonBlockingHashMapLong;
import org.cliffc.high_scale_lib.NonBlockingHashMapLong.IteratorLong;
/**
*
* @author pron
*/
class JMXActorsMonitor implements NotificationListener, ActorsMXBean {
private static final JMXActorsMonitor instance = new JMXActorsMonitor();
public static JMXActorsMonitor getInstance() {
return instance;
}
private final String mbeanName;
private boolean registered;
private final NonBlockingHashMapLong> actors = new NonBlockingHashMapLong>();
private final NonBlockingHashMapLong watchedActors = new NonBlockingHashMapLong();
private long lastCollectTime;
private final LongAdder activeCount = new LongAdder();
private JMXActorsMonitor() {
this.mbeanName = "co.paralleluniverse:type=Actors";
registerMBean();
lastCollectTime = nanoTime();
}
@SuppressWarnings({"CallToPrintStackTrace", "CallToThreadDumpStack"})
private void registerMBean() {
try {
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
final ObjectName mxbeanName = new ObjectName(mbeanName);
mbs.registerMBean(this, mxbeanName);
this.registered = true;
} catch (InstanceAlreadyExistsException ex) {
throw new RuntimeException(ex);
} catch (MBeanRegistrationException ex) {
ex.printStackTrace();
} catch (NotCompliantMBeanException ex) {
throw new AssertionError(ex);
} catch (MalformedObjectNameException ex) {
throw new AssertionError(ex);
}
MonitoringServices.getInstance().addPerfNotificationListener(this, mbeanName);
}
@SuppressWarnings({"CallToPrintStackTrace", "CallToThreadDumpStack"})
private void unregister() {
try {
if (registered) {
MonitoringServices.getInstance().removePerfNotificationListener(this);
ManagementFactory.getPlatformMBeanServer().unregisterMBean(new ObjectName(mbeanName));
}
this.registered = false;
} catch (InstanceNotFoundException ex) {
ex.printStackTrace();
} catch (MBeanRegistrationException ex) {
ex.printStackTrace();
} catch (MalformedObjectNameException ex) {
throw new AssertionError(ex);
}
}
@Override
public void handleNotification(Notification notification, Object handback) {
if ("perfTimer".equals(notification.getType()))
refresh();
}
@Override
public void refresh() {
collectAndResetCounters();
}
public boolean isRegistered() {
return registered;
}
private void collectAndResetCounters() {
if (isRegistered()) {
collectAndResetCounters(nanoTime() - lastCollectTime);
}
}
protected void collectAndResetCounters(long intervalNanos) {
lastCollectTime = nanoTime();
}
private long nanoTime() {
return System.nanoTime();
}
void actorStarted(ActorRef> actor) {
activeCount.increment();
actors.put(LocalActorUtil.getStrand(actor).getId(), actor);
}
void actorTerminated(ActorRef> actor) {
activeCount.decrement();
actors.remove(LocalActorUtil.getStrand(actor).getId());
}
@Override
public int getNumActiveActors() {
return activeCount.intValue();
}
@Override
public long[] getAllActorIds() {
int size = actors.size();
IteratorLong it = (IteratorLong) actors.keys();
long[] ids = new long[size];
int i = 0;
while (it.hasNext() && i < size) {
ids[i] = it.nextLong();
i++;
}
if (i < size)
return Arrays.copyOf(ids, i);
else
return ids; // might not include all nw fibers
}
@Override
public String getStackTrace(long actorId) {
ActorRef actor = actors.get(actorId);
if (actor == null)
return null;
return getStackTrace(actor);
}
private String getStackTrace(ActorRef actor) {
final StackTraceElement[] stackTrace = LocalActorUtil.getStackTrace(actor);
final StringBuilder sb = new StringBuilder();
for (StackTraceElement ste : stackTrace)
sb.append(ste).append('\n');
return sb.toString();
}
@Override
public String[] getMailbox(long actorId) {
ActorRef actor = actors.get(actorId);
if (actor == null)
return null;
return getMailbox(actor);
}
private String[] getMailbox(ActorRef actor) {
List