Index: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jmx/EventListenerMBean.java =================================================================== --- jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jmx/EventListenerMBean.java (revision 1754256) +++ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jmx/EventListenerMBean.java (working copy) @@ -84,6 +84,13 @@ boolean isDateAccessedFromExternalEvent(); /** + * The time difference between the current system time and the head (oldest) + * element in the queue in milliseconds. This method returns zero if the + * queue is empty. + */ + long getQueueBacklogMillis(); + + /** * {@link org.apache.jackrabbit.api.stats.TimeSeries time series} of the number of * items related to generating observation events that are currently queued by the * system. The exact nature of these items is implementation specific and might not Index: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jmx/package-info.java =================================================================== --- jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jmx/package-info.java (revision 1754256) +++ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jmx/package-info.java (working copy) @@ -18,5 +18,5 @@ /** * JMX management interfaces for JCR. */ -@aQute.bnd.annotation.Version("2.1.0") +@aQute.bnd.annotation.Version("2.2.0") package org.apache.jackrabbit.api.jmx; Index: jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/observation/ListenerTracker.java =================================================================== --- jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/observation/ListenerTracker.java (revision 1754256) +++ jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/observation/ListenerTracker.java (working copy) @@ -71,6 +71,8 @@ private final AtomicLong eventDeliveryTime = new AtomicLong(); + private final AtomicLong headTimestamp = new AtomicLong(); + private final TimeSeriesMax queueLength = new TimeSeriesMax(); private final TimeSeriesRecorder eventCount = new TimeSeriesRecorder(true); @@ -142,6 +144,19 @@ } /** + * Applications should call this to report the current queue length when an + * item is removed from the queue. + * + * @param length the length of the queue after the item was removed. + * @param headTimestamp the time in milliseconds when the head item was + * created and put into the queue. + */ + public void recordQueueLength(long length, long headTimestamp) { + queueLength.recordValue(length); + this.headTimestamp.set(length == 0 ? 0 : headTimestamp); + } + + /** * Records the number of measured values over the past second and resets * the counter. This method should be scheduled to be called once per * second. @@ -295,6 +310,14 @@ return dateAccessedFromExternalEvent.get(); } @Override + public long getQueueBacklogMillis() { + long t = headTimestamp.get(); + if (t > 0) { + t = currentTimeMillis() - t; + } + return t; + } + @Override public CompositeData getQueueLength() { return asCompositeData(queueLength, "queueLength"); }