S
Simon Brooke
I'm developing an abstract monitoring framework which consists of a
(potentially) large number of simple agents each of which watches a single
thing, where these things change slowly and infrequently. My Watcher
objects sleep for periods typically from a few hours up to many days, wake
up, check the thing they're watching in a few seconds, and then if
everything's OK go to sleep again. In implementation terms it's incredibly
easy to do this by giving each Watcher a thread of its own:
/** a token to identify the sleep time in the configuration */
public static final String INTERVALTOKEN = "period";
/** how many milliseconds I sleep between periods of activity */
protected long winks = 5 * 60 * 1000;
/** my thread */
protected Thread thread = null;
/** the exceptions which occurred as I was watching */
protected Vector whinges = new Vector( );
/**
* initialise me with this configuration
*/
public void init( Map config ) throws AlertingException
{
....
Object val = config.get( INTERVALTOKEN );
if ( val == null )
{
val = config.get( "p" );
}
if ( val != null )
{
winks = (long) ( Integer.parseInt( val.toString( ) ) * 1000 );
}
...
}
/**
* perform a check to see whether the event I am watching for has
* occurred.
*
* @return a vector of maps each one of which represents an alert which
* should be sent. If no alerts should be sent, return an empty
* vector.
*/
protected abstract Vector check( ) throws Exception;
/**
* periodically wake up check the things I'm watching. If any have
* changed send appropriate alerts
*/
public void run( )
{
while ( thread != null )
{
if ( whinges.size( ) < TOOMANYERRORS)
{
try
{
Vector alerts = check( );
if ( alerts != null )
{
Enumeration e = alerts.elements( );
while ( e.hasMoreElements( ) )
{
Map context = (Map) e.nextElement( );
try
{
sendAlert( context );
mark( context );
}
catch ( Exception oops )
{
whinge( oops );
whinges.add( oops );
}
}
}
}
catch ( Exception whinge )
{
whinge( whinge );
whinges.add( whinge );
}
}
else
{ // stop the thread!
stop( );
}
try
{
Thread.sleep( winks );
}
catch ( InterruptedException wakeywakey )
{
break;
}
}
}
But what's bothering me is what this costs. It particularly bothers me
because, while at this stage in the development of my system I'm dealing
with a few tens of these objects, in the long term I could be dealing with
several hundreds.
Are threads essentially very lightweight things which allow this framework
to be efficient, or are they quite heavyweight and I'd be better working
on an architecture where a single thread wakes up periodically and polls
watchers for whether they want to run?
--
(e-mail address removed) (Simon Brooke) http://www.jasmine.org.uk/~simon/
Ye hypocrites! are these your pranks? To murder men and give God thanks?
Desist, for shame! Proceed no further: God won't accept your thanks for
murther
-- Robert Burns, 'Thanksgiving For a National Victory'
(potentially) large number of simple agents each of which watches a single
thing, where these things change slowly and infrequently. My Watcher
objects sleep for periods typically from a few hours up to many days, wake
up, check the thing they're watching in a few seconds, and then if
everything's OK go to sleep again. In implementation terms it's incredibly
easy to do this by giving each Watcher a thread of its own:
/** a token to identify the sleep time in the configuration */
public static final String INTERVALTOKEN = "period";
/** how many milliseconds I sleep between periods of activity */
protected long winks = 5 * 60 * 1000;
/** my thread */
protected Thread thread = null;
/** the exceptions which occurred as I was watching */
protected Vector whinges = new Vector( );
/**
* initialise me with this configuration
*/
public void init( Map config ) throws AlertingException
{
....
Object val = config.get( INTERVALTOKEN );
if ( val == null )
{
val = config.get( "p" );
}
if ( val != null )
{
winks = (long) ( Integer.parseInt( val.toString( ) ) * 1000 );
}
...
}
/**
* perform a check to see whether the event I am watching for has
* occurred.
*
* @return a vector of maps each one of which represents an alert which
* should be sent. If no alerts should be sent, return an empty
* vector.
*/
protected abstract Vector check( ) throws Exception;
/**
* periodically wake up check the things I'm watching. If any have
* changed send appropriate alerts
*/
public void run( )
{
while ( thread != null )
{
if ( whinges.size( ) < TOOMANYERRORS)
{
try
{
Vector alerts = check( );
if ( alerts != null )
{
Enumeration e = alerts.elements( );
while ( e.hasMoreElements( ) )
{
Map context = (Map) e.nextElement( );
try
{
sendAlert( context );
mark( context );
}
catch ( Exception oops )
{
whinge( oops );
whinges.add( oops );
}
}
}
}
catch ( Exception whinge )
{
whinge( whinge );
whinges.add( whinge );
}
}
else
{ // stop the thread!
stop( );
}
try
{
Thread.sleep( winks );
}
catch ( InterruptedException wakeywakey )
{
break;
}
}
}
But what's bothering me is what this costs. It particularly bothers me
because, while at this stage in the development of my system I'm dealing
with a few tens of these objects, in the long term I could be dealing with
several hundreds.
Are threads essentially very lightweight things which allow this framework
to be efficient, or are they quite heavyweight and I'd be better working
on an architecture where a single thread wakes up periodically and polls
watchers for whether they want to run?
--
(e-mail address removed) (Simon Brooke) http://www.jasmine.org.uk/~simon/
Ye hypocrites! are these your pranks? To murder men and give God thanks?
Desist, for shame! Proceed no further: God won't accept your thanks for
murther
-- Robert Burns, 'Thanksgiving For a National Victory'