org.hd.d.pg2k.webSvr.util
Class StatsSink

java.lang.Object
  extended by org.hd.d.pg2k.webSvr.util.StatsSink

public final class StatsSink
extends java.lang.Object

Web-server dynamic (authenticated) stats-collection support. This enables a number of types of stats to be collected in such a way as to be unlikely to be accidentally triggered by a spider or off a cached Web page/URL somewhere.

This also facilitates sampling stats so as to not pester any one user too much or gather more than one data point at a time from them.

Most operations on this class are constant time on average, although mutators in particular may perform maintenance work that does not raise the O() cost when amortised across all calls.

Access to all significant data structures is under the class lock.


Nested Class Summary
static class StatsSink.AbstractStatsListener
          Abstract/base listener object waiting for stats to arrive.
 
Field Summary
private static java.util.Map<java.lang.String,StatsSink.AbstractStatsListener> byDataPointID
          Map from uniqueDataPointID to Listener; never null.
private static java.util.Map<java.lang.String,StatsSink.AbstractStatsListener> byListenerID
          Map from uniqueListenerID to Listener; never null.
static java.lang.String HTTP_ID_PARAM_NAME
          The name of the HTTP parameter carrying our mandatory unique event ID value.
 
Constructor Summary
private StatsSink()
          Prevent construction of an instance.
 
Method Summary
private static void _clearExpiredEntries()
          Clear all expired entries (with the lock held).
private static StatsSink.AbstractStatsListener _getAndRemoveListenerByListenerID(java.lang.String listenerID)
          Find (and remove) listener identified by listener ID, or null if none live by that ID.
private static void _sometimesClearExpiredEntries()
          Spend on average O(1) (ie constant) time expiring old entries.
static java.lang.String acceptEvent(javax.servlet.http.HttpServletRequest request, javax.servlet.ServletContext context)
          Accept an inbound HTTP stats event.
static void addListenerForDataPoint(StatsSink.AbstractStatsListener newAsl)
          Add new listener for named unique data point.
static boolean isListenerLiveForDataPoint(java.lang.String uniqueDataPointID)
          Returns true if there is a live (non-expired) listener for a given data-point ID.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

HTTP_ID_PARAM_NAME

public static final java.lang.String HTTP_ID_PARAM_NAME
The name of the HTTP parameter carrying our mandatory unique event ID value.

See Also:
Constant Field Values

byListenerID

private static final java.util.Map<java.lang.String,StatsSink.AbstractStatsListener> byListenerID
Map from uniqueListenerID to Listener; never null. Incoming stats events are looked up in here by ID.


byDataPointID

private static final java.util.Map<java.lang.String,StatsSink.AbstractStatsListener> byDataPointID
Map from uniqueDataPointID to Listener; never null. The normal programmatic interface makes use of this.

Constructor Detail

StatsSink

private StatsSink()
Prevent construction of an instance.

Method Detail

_getAndRemoveListenerByListenerID

private static StatsSink.AbstractStatsListener _getAndRemoveListenerByListenerID(java.lang.String listenerID)
Find (and remove) listener identified by listener ID, or null if none live by that ID. Run under the class lock.

Has removed the listener from the database, if present beforehand, by the time it returns.


acceptEvent

public static java.lang.String acceptEvent(javax.servlet.http.HttpServletRequest request,
                                           javax.servlet.ServletContext context)
Accept an inbound HTTP stats event. We will filter it and decide whether to pass it on to an agent, and if so, which agent.

No lock is held while the agent/handler is called.

We must see an "ID" parameter with the unique allocated ID, or this is rejected out of hand (ignored).

This may return a non-null value that is treated as a URL to redirect to. The returned URL may be root-relative.

Parameters:
request - valid non-null HTTP request object; never null
Returns:
URL, possibly root-relative, to redirect to, or null if none

isListenerLiveForDataPoint

public static boolean isListenerLiveForDataPoint(java.lang.String uniqueDataPointID)
Returns true if there is a live (non-expired) listener for a given data-point ID. Useful for helping ensure that we don't try to collect more than one value for a data point at once.

This is fast and read-only.

Parameters:
uniqueDataPointID - the unique ID; must not be null

addListenerForDataPoint

public static void addListenerForDataPoint(StatsSink.AbstractStatsListener newAsl)
Add new listener for named unique data point. Not added if already expired, though an extant listener will be removed.

Any extant listener for the same data point is removed.

This may do clean-up work on some calls.

This call has an average constant (ie O(1)) call time.

A caller should be careful to avoid passing in strong references to objects that should otherwise be GCed while the listener remains active. It may be wise to use top-level or static inner classes only for example.


_sometimesClearExpiredEntries

private static void _sometimesClearExpiredEntries()
Spend on average O(1) (ie constant) time expiring old entries.


_clearExpiredEntries

private static void _clearExpiredEntries()
Clear all expired entries (with the lock held).


DHD Multimedia Gallery V1.57.21

Copyright (c) 1996-2011, Damon Hart-Davis. All rights reserved.