Allow invoker units to specify their own long threshold. Do away with the
invoker-wide long threshold configuration. git-svn-id: https://samskivert.googlecode.com/svn/trunk@2133 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -26,31 +26,27 @@ import java.util.Iterator;
|
|||||||
import com.samskivert.Log;
|
import com.samskivert.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The invoker is used to invoke self-contained units of code on an
|
* The invoker is used to invoke self-contained units of code on an invoking thread. Each invoker
|
||||||
* invoking thread. Each invoker is associated with its own thread and
|
* is associated with its own thread and that thread is used to invoke all of the units posted to
|
||||||
* that thread is used to invoke all of the units posted to that invoker
|
* that invoker in the order in which they were posted. The invoker also provides a convenient
|
||||||
* in the order in which they were posted. The invoker also provides a
|
* mechanism for processing the result of an invocation back on the main thread.
|
||||||
* convenient mechanism for processing the result of an invocation back on
|
|
||||||
* the main thread.
|
|
||||||
*
|
*
|
||||||
* <p> The invoker is a useful tool for services that need to block and
|
* <p> The invoker is a useful tool for services that need to block and therefore cannot be run on
|
||||||
* therefore cannot be run on the main thread. For example, an interactive
|
* the main thread. For example, an interactive application might provide an invoker on which to
|
||||||
* application might provide an invoker on which to run database queries.
|
* run database queries.
|
||||||
*
|
*
|
||||||
* <p> Bear in mind that each invoker instance runs units on its own
|
* <p> Bear in mind that each invoker instance runs units on its own thread and care must be taken
|
||||||
* thread and care must be taken to ensure that code running on separate
|
* to ensure that code running on separate invokers properly synchronizes access to shared
|
||||||
* invokers properly synchronizes access to shared information. Where
|
* information. Where possible, complete isolation of the services provided by a particular invoker
|
||||||
* possible, complete isolation of the services provided by a particular
|
* is desirable.
|
||||||
* invoker is desirable.
|
|
||||||
*/
|
*/
|
||||||
public class Invoker extends LoopingThread
|
public class Invoker extends LoopingThread
|
||||||
implements RunQueue
|
implements RunQueue
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The unit encapsulates a unit of executable code that will be run on
|
* The unit encapsulates a unit of executable code that will be run on the invoker thread. It
|
||||||
* the invoker thread. It also provides facilities for additional code
|
* also provides facilities for additional code to be run on the main thread once the primary
|
||||||
* to be run on the main thread once the primary code has completed on
|
* code has completed on the invoker thread.
|
||||||
* the invoker thread.
|
|
||||||
*/
|
*/
|
||||||
public static abstract class Unit implements Runnable
|
public static abstract class Unit implements Runnable
|
||||||
{
|
{
|
||||||
@@ -63,45 +59,51 @@ public class Invoker extends LoopingThread
|
|||||||
this("Unknown");
|
this("Unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates an invoker unit which will report the supplied name in
|
/** Creates an invoker unit which will report the supplied name in {@link #toString}. */
|
||||||
* {@link #toString}. */
|
|
||||||
public Unit (String name)
|
public Unit (String name)
|
||||||
{
|
{
|
||||||
_name = name;
|
_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called on the invoker thread and should be used
|
* This method is called on the invoker thread and should be used to perform the primary
|
||||||
* to perform the primary function of the unit. It can return true
|
* function of the unit. It can return true to cause the {@link #handleResult} method to be
|
||||||
* to cause the <code>handleResult</code> method to be
|
* subsequently invoked on the dobjmgr thread (generally to allow the results of the
|
||||||
* subsequently invoked on the dobjmgr thread (generally to allow
|
* invocation to be acted upon back in the context of the regular world) or false to
|
||||||
* the results of the invocation to be acted upon back in the
|
* indicate that no further processing should be performed.
|
||||||
* context of the regular world) or false to indicate that no
|
|
||||||
* further processing should be performed.
|
|
||||||
*
|
*
|
||||||
* @return true if the <code>handleResult</code> method should be
|
* @return true if the {@link #handleResult} method should be called on the main thread,
|
||||||
* invoked on the main thread, false if not.
|
* false if not.
|
||||||
*/
|
*/
|
||||||
public abstract boolean invoke ();
|
public abstract boolean invoke ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invocation unit implementations can implement this function to
|
* Invocation unit implementations can implement this function to perform any post unit
|
||||||
* perform any post-unit-invocation processing back on the main
|
* invocation processing back on the main thread. It will be invoked if {@link #invoke}
|
||||||
* thread. It will be invoked if <code>invoke</code> returns true.
|
* returns true.
|
||||||
*/
|
*/
|
||||||
public void handleResult ()
|
public void handleResult ()
|
||||||
{
|
{
|
||||||
// do nothing by default
|
// do nothing by default
|
||||||
}
|
}
|
||||||
|
|
||||||
// we want to be a runnable to make the receiver interface simple,
|
// we want to be a runnable to make the receiver interface simple, but we'd like for
|
||||||
// but we'd like for invocation unit implementations to be able to
|
// invocation unit implementations to be able to put their result handling code into an
|
||||||
// put their result handling code into an aptly named method
|
// aptly named method
|
||||||
public void run ()
|
public void run ()
|
||||||
{
|
{
|
||||||
handleResult();
|
handleResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the duration beyond which this invoker unit will be considered to be running too
|
||||||
|
* long and result in a warning being logged. The default is 500ms.
|
||||||
|
*/
|
||||||
|
public long getLongThreshold ()
|
||||||
|
{
|
||||||
|
return DEFAULT_LONG_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the name of this invoker. */
|
/** Returns the name of this invoker. */
|
||||||
public String toString ()
|
public String toString ()
|
||||||
{
|
{
|
||||||
@@ -112,8 +114,7 @@ public class Invoker extends LoopingThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an invoker that will post results to the supplied result
|
* Creates an invoker that will post results to the supplied result receiver.
|
||||||
* receiver.
|
|
||||||
*/
|
*/
|
||||||
public Invoker (String name, RunQueue resultReceiver)
|
public Invoker (String name, RunQueue resultReceiver)
|
||||||
{
|
{
|
||||||
@@ -122,18 +123,7 @@ public class Invoker extends LoopingThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the duration after which an invoker unit will be considered
|
* Posts a unit to this invoker for subsequent invocation on the invoker's thread.
|
||||||
* "long". When they complete, long units have a warning message
|
|
||||||
* logged. The default long threshold is 500 milliseconds.
|
|
||||||
*/
|
|
||||||
public void setLongThresholds (long longThreshold)
|
|
||||||
{
|
|
||||||
_longThreshold = longThreshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Posts a unit to this invoker for subsequent invocation on the
|
|
||||||
* invoker's thread.
|
|
||||||
*/
|
*/
|
||||||
public void postUnit (Unit unit)
|
public void postUnit (Unit unit)
|
||||||
{
|
{
|
||||||
@@ -184,8 +174,7 @@ public class Invoker extends LoopingThread
|
|||||||
try {
|
try {
|
||||||
willInvokeUnit(unit, start);
|
willInvokeUnit(unit, start);
|
||||||
if (unit.invoke()) {
|
if (unit.invoke()) {
|
||||||
// if it returned true, we post it to the receiver thread
|
// if it returned true, post it to the receiver thread for result processing
|
||||||
// to invoke the result processing
|
|
||||||
_receiver.postRunnable(unit);
|
_receiver.postRunnable(unit);
|
||||||
}
|
}
|
||||||
didInvokeUnit(unit, start);
|
didInvokeUnit(unit, start);
|
||||||
@@ -197,8 +186,8 @@ public class Invoker extends LoopingThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuts down the invoker thread by queueing up a unit that will cause
|
* Shuts down the invoker thread by queueing up a unit that will cause the thread to exit after
|
||||||
* the thread to exit after all currently queued units are processed.
|
* all currently queued units are processed.
|
||||||
*/
|
*/
|
||||||
public void shutdown ()
|
public void shutdown ()
|
||||||
{
|
{
|
||||||
@@ -214,8 +203,8 @@ public class Invoker extends LoopingThread
|
|||||||
* Called before we process an invoker unit.
|
* Called before we process an invoker unit.
|
||||||
*
|
*
|
||||||
* @param unit the unit about to be invoked.
|
* @param unit the unit about to be invoked.
|
||||||
* @param start a timestamp recorded immediately before invocation if
|
* @param start a timestamp recorded immediately before invocation if {@link #PERF_TRACK} is
|
||||||
* {@link #PERF_TRACK} is enabled, 0L otherwise.
|
* enabled, 0L otherwise.
|
||||||
*/
|
*/
|
||||||
protected void willInvokeUnit (Unit unit, long start)
|
protected void willInvokeUnit (Unit unit, long start)
|
||||||
{
|
{
|
||||||
@@ -225,8 +214,8 @@ public class Invoker extends LoopingThread
|
|||||||
* Called before we process an invoker unit.
|
* Called before we process an invoker unit.
|
||||||
*
|
*
|
||||||
* @param unit the unit about to be invoked.
|
* @param unit the unit about to be invoked.
|
||||||
* @param start a timestamp recorded immediately before invocation if
|
* @param start a timestamp recorded immediately before invocation if {@link #PERF_TRACK} is
|
||||||
* {@link #PERF_TRACK} is enabled, 0L otherwise.
|
* enabled, 0L otherwise.
|
||||||
*/
|
*/
|
||||||
protected void didInvokeUnit (Unit unit, long start)
|
protected void didInvokeUnit (Unit unit, long start)
|
||||||
{
|
{
|
||||||
@@ -237,11 +226,10 @@ public class Invoker extends LoopingThread
|
|||||||
recordMetrics(key, duration);
|
recordMetrics(key, duration);
|
||||||
|
|
||||||
// report long runners
|
// report long runners
|
||||||
if (duration > _longThreshold) {
|
if (duration > unit.getLongThreshold()) {
|
||||||
String howLong = (duration >= 10*_longThreshold) ?
|
String howLong = (duration >= 10*unit.getLongThreshold()) ? "Really long" : "Long";
|
||||||
"Really long" : "Long";
|
Log.warning(howLong + " invoker unit [unit=" + unit + " (" + key +
|
||||||
Log.warning(howLong + " invoker unit [unit=" + unit +
|
"), time=" + duration + "ms].");
|
||||||
" (" + key + "), time=" + duration + "ms].");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,8 +258,7 @@ public class Invoker extends LoopingThread
|
|||||||
|
|
||||||
public String toString () {
|
public String toString () {
|
||||||
int count = _histo.size();
|
int count = _histo.size();
|
||||||
return _totalElapsed + "ms/" + count + " = " +
|
return _totalElapsed + "ms/" + count + " = " + (_totalElapsed/count) + "ms avg " +
|
||||||
(_totalElapsed/count) + "ms avg " +
|
|
||||||
StringUtil.toString(_histo.getBuckets());
|
StringUtil.toString(_histo.getBuckets());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,15 +274,13 @@ public class Invoker extends LoopingThread
|
|||||||
protected RunQueue _receiver;
|
protected RunQueue _receiver;
|
||||||
|
|
||||||
/** Tracks the counts of invocations by unit's class. */
|
/** Tracks the counts of invocations by unit's class. */
|
||||||
protected HashMap<Object,UnitProfile> _tracker =
|
protected HashMap<Object,UnitProfile> _tracker = new HashMap<Object,UnitProfile>();
|
||||||
new HashMap<Object,UnitProfile>();
|
|
||||||
|
|
||||||
/** The total number of invoker units run since the last report. */
|
/** The total number of invoker units run since the last report. */
|
||||||
protected int _unitsRun;
|
protected int _unitsRun;
|
||||||
|
|
||||||
/** The duration of time after which we consider a unit to be delinquent
|
/** The duration of time after which we consider a unit to be delinquent and log a warning. */
|
||||||
* and log a warning. */
|
protected static final long DEFAULT_LONG_THRESHOLD = 500L;
|
||||||
protected long _longThreshold = 500L;
|
|
||||||
|
|
||||||
/** Whether or not to track invoker unit performance. */
|
/** Whether or not to track invoker unit performance. */
|
||||||
protected static final boolean PERF_TRACK = true;
|
protected static final boolean PERF_TRACK = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user