Skip to content

Commit

Permalink
Implemented "Support grizzly-memcached's monitoring features using Gr…
Browse files Browse the repository at this point in the history
…izzly JMX"(eclipse-ee4j#13)

+ Added stats(Keyed object which is generally related to network connection managed in the basic object pool).
  • Loading branch information
carryel committed Aug 22, 2024
1 parent 2e5567c commit 0a6415d
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

import org.glassfish.grizzly.Grizzly;
import org.glassfish.grizzly.monitoring.DefaultMonitoringConfig;
import org.glassfish.grizzly.monitoring.MonitoringAware;
import org.glassfish.grizzly.monitoring.MonitoringConfig;
import org.glassfish.grizzly.monitoring.MonitoringUtils;

import java.util.Collection;
import java.util.Map;
import java.util.OptionalInt;
import java.util.concurrent.BlockingQueue;
Expand Down Expand Up @@ -110,7 +112,7 @@ public void createAllMinObjects(final K key) throws NoValidObjectException, Time
}
QueuePool<V> pool = keyedObjectPool.get(key);
if (pool == null) {
final QueuePool<V> newPool = new QueuePool<V>(max);
final QueuePool<V> newPool = new QueuePool<V>(key.toString(), max);
final QueuePool<V> oldPool = keyedObjectPool.putIfAbsent(key, newPool);
pool = oldPool == null ? newPool : oldPool;
}
Expand Down Expand Up @@ -189,7 +191,7 @@ public V borrowObject(final K key, final long timeoutInMillis)
}
QueuePool<V> pool = keyedObjectPool.get(key);
if (pool == null) {
final QueuePool<V> newPool = new QueuePool<V>(max);
final QueuePool<V> newPool = new QueuePool<V>(key.toString(), max);
final QueuePool<V> oldPool = keyedObjectPool.putIfAbsent(key, newPool);
pool = oldPool == null ? newPool : oldPool;
}
Expand Down Expand Up @@ -610,6 +612,11 @@ public String getKeys() {
return keyedObjectPool.keySet().toString();
}

public Collection<QueuePool<V>> getValues() {
return keyedObjectPool.values();
}


/**
* {@inheritDoc}
*/
Expand All @@ -633,36 +640,61 @@ private Object createJmxManagementObject() {
* If this pool has max size(bounded pool), it uses {@link LinkedBlockingQueue}.
* Otherwise, this pool uses unbounded queue like {@link LinkedBlockingQueue} for idle objects.
*/
private static class QueuePool<V> {
public static class QueuePool<V> implements MonitoringAware<ObjectPoolProbe> {
private final AtomicInteger poolSizeHint = new AtomicInteger();
private volatile int peakSizeHint = 0;
private final BlockingQueue<V> queue;
private final AtomicBoolean destroyed = new AtomicBoolean();
private final String name;

private final DefaultMonitoringConfig<ObjectPoolProbe> queuePoolMonitoringConfig =
new DefaultMonitoringConfig<ObjectPoolProbe>(ObjectPoolProbe.class) {

private QueuePool(final int max) {
@Override
public Object createManagementObject() {
return createJmxManagementObject();
}
};

private QueuePool(final String name, final int max) {
if (max <= 0 || max == Integer.MAX_VALUE) {
queue = new LinkedTransferQueue<>();

} else {
queue = new LinkedBlockingQueue<V>(max);
}
this.name = name;
}

private int getPoolSize() {
public int getPoolSize() {
return poolSizeHint.get();
}

private int getPeakCount() {
public int getPeakCount() {
return peakSizeHint;
}

private int getActiveCount() {
public int getActiveCount() {
return poolSizeHint.get() - queue.size();
}

private int getIdleCount() {
public int getIdleCount() {
return queue.size();
}

@Override
public MonitoringConfig<ObjectPoolProbe> getMonitoringConfig() {
return queuePoolMonitoringConfig;
}

public String getName() {
return name;
}

private Object createJmxManagementObject() {
return MonitoringUtils
.loadJmxObject("org.glassfish.grizzly.memcached.pool.jmx.KeyedObject", this, QueuePool.class);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,22 @@
import org.glassfish.gmbal.GmbalMBean;
import org.glassfish.gmbal.ManagedObject;

import java.util.Collection;
import java.util.HashSet;

/**
* JMX managed object for object pool implementations.
*/
@ManagedObject
@Description("Basic object pool with a pool of objects (generally related to network connections) for each key.")
public class BaseObjectPool extends JmxObject {
public class BaseObjectPool<K, V> extends JmxObject {

private final org.glassfish.grizzly.memcached.pool.BaseObjectPool<K, V> pool;

private final org.glassfish.grizzly.memcached.pool.BaseObjectPool pool;
private GrizzlyJmxManager mom;
private final Collection<Object> keyedObjectJmx = new HashSet<>();

public BaseObjectPool(final org.glassfish.grizzly.memcached.pool.BaseObjectPool pool) {
public BaseObjectPool(final org.glassfish.grizzly.memcached.pool.BaseObjectPool<K, V> pool) {
this.pool = pool;
}

Expand All @@ -45,10 +51,13 @@ public String getJmxName() {

@Override
protected void onRegister(GrizzlyJmxManager mom, GmbalMBean bean) {
this.mom = mom;
rebuildSubTree();
}

@Override
protected void onDeregister(GrizzlyJmxManager mom) {
this.mom = null;
}

/**
Expand Down Expand Up @@ -161,6 +170,18 @@ public String getKeys() {
return pool.getKeys();
}

private void rebuildSubTree() {
keyedObjectJmx.forEach(jmxObj -> mom.deregister(jmxObj));
keyedObjectJmx.clear();

final Collection<org.glassfish.grizzly.memcached.pool.BaseObjectPool.QueuePool<V>> keyedObjects = pool.getValues();
keyedObjects.forEach(keyedObj -> {
final Object jmxObj = keyedObj.getMonitoringConfig().createManagementObject();
mom.register(this, jmxObj);
keyedObjectJmx.add(jmxObj);
});
}

@ManagedData(name = "Object Pool Stat")
private static class CompositeObjectPoolStat {
@ManagedAttribute(id = "total-pools")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.glassfish.grizzly.memcached.pool.jmx;

import org.glassfish.gmbal.Description;
import org.glassfish.gmbal.GmbalMBean;
import org.glassfish.gmbal.ManagedAttribute;
import org.glassfish.gmbal.ManagedData;
import org.glassfish.gmbal.ManagedObject;
import org.glassfish.grizzly.jmxbase.GrizzlyJmxManager;
import org.glassfish.grizzly.memcached.pool.BaseObjectPool;
import org.glassfish.grizzly.monitoring.jmx.JmxObject;

/**
* JMX managed object for object pool's keyed object implementations.
*/
@ManagedObject
@Description("Keyed object managed in the basic object pool(generally related to network connection)")
public class KeyedObject extends JmxObject {

private final BaseObjectPool.QueuePool pool;

public KeyedObject(final BaseObjectPool.QueuePool pool) {
this.pool = pool;
}

@Override
public String getJmxName() {
return pool.getName();
}

@Override
protected void onRegister(GrizzlyJmxManager mom, GmbalMBean bean) {
}

@Override
protected void onDeregister(GrizzlyJmxManager mom) {
}

/**
* Returns the Java type of the managed object pool
*
* @return the Java type of the managed object pool.
*/
@ManagedAttribute(id = "keyed-object-type")
@Description("The Java type of the keyed object implementation being used.")
public String getKeyedObjectType() {
return pool.getClass().getName();
}

@ManagedAttribute(id = "object-stat")
@Description("The stat of objects in this pool.")
public CompositeObjectStat getObjectStat() {
return new CompositeObjectStat(pool.getPoolSize(), pool.getPeakCount(), pool.getActiveCount(),
pool.getIdleCount());
}

@ManagedData(name="Object Stat")
private static class CompositeObjectStat {
@ManagedAttribute(id = "objects")
@Description("The total number of objects currently idle and active in this pool or a negative value if unsupported.")
private final int objectSize;

@ManagedAttribute(id = "peak")
@Description("The peak number of objects or a negative value if unsupported.")
private final int peakCount;

@ManagedAttribute(id = "active")
@Description("The number of objects currently borrowed in this pool or a negative value if unsupported.")
private final int activeCount;

@ManagedAttribute(id = "idle")
@Description("The number of objects currently idle in this pool or a negative value if unsupported.")
private final int idleCount;

private CompositeObjectStat(int objectSize, int peakCount, int activeCount, int idleCount) {
this.objectSize = objectSize;
this.peakCount = peakCount;
this.activeCount = activeCount;
this.idleCount = idleCount;
}
}
}

0 comments on commit 0a6415d

Please sign in to comment.