org.hd.d.pg2k.clApp.atHome
Class AHStandaloneMain

java.lang.Object
  extended by org.hd.d.pg2k.clApp.atHome.AHStandaloneMain

public final class AHStandaloneMain
extends java.lang.Object

Core of at-home program: suitable to drive from a bare command-line or better. This can also form the core of a more-sophisticated GUI-based (eg JWS) app.

Author:
dhd

Nested Class Summary
private static class AHStandaloneMain.Callback
          Container of various items of information we need to run the worker threads.
private static class AHStandaloneMain.FakeTunnel
          Fake data source cobbled together to just support the actions some Scorers and their support need.
 
Field Summary
private static java.lang.Object _submitLock
          Lock used to serialise new/best Scorer submissions back to the server; never null.
private static boolean ALLOW_FILESYSTEM_TNCACHE
          If true then attempt to use a primitive filesystem thumbnail/data cache where permitted.
(package private)  javax.jnlp.BasicService bs
          Handle on JWS basic service; null if none.
private  AHStandaloneMain.Callback cb
          Callback object for reporting new/best Scorer; never null.
private  int chunkMs
          Target CPU work chunk in ms; strictly positive.
static java.lang.String DATA_BLOCK_END
          End sequence; we look for a line containing this to start our data.
static java.lang.String DATA_BLOCK_START
          Start sequence; we look for a line containing this to start our data.
static int DEFAULT_CPU_CHUNK_MS
          Default target CPU work chunk in ms; strictly positive.
static int DEFAULT_CPU_PERCENT
          Default target fractional CPU usage (of entire host) in exclusive range ]1,100[, ie strictly positive.
private static java.lang.String DEFAULT_SERVER
          Default server host name to connect back to; the generic/main host in this case.
private static java.lang.String DEFAULT_TNCACHE_DIR
          Default directory in which cache thumbnail/playback data; always relative to pwd/cwd.
static SimpleLoggerIF defaultLogger
          Default logger: writes to stdout.
(package private)  javax.jnlp.ExtendedService exs
          Handle on JWS extended service; null if none.
private  AHStandaloneMain.FakeTunnel fakeTunnel
          Synthetic data pipeline tunnel back to server; never null.
(package private)  javax.jnlp.FileOpenService fos
          Handle on JWS file-open service; null if none.
private  int genTimeRemaining
          Time remaining for this generation; reset if a new/best Scorer is found.
private static java.lang.String GETDATA_METHOD
          Method to use in getData() to connect to server (POST or GET).
private  long lastFetchedCalibrationData
          Last time we polled the server for calibration data.
private  ScoreAndConf lastSAC
          Score/confidence of last Scorer reported; never null.
private  SimpleLoggerIF log
          Logger; never null.
static int MIN_GENERATION_MS
          Minimum time (in ms) spent working on one generation; strictly positive.
static int MIN_SCORER_SERVER_REPORT_GAP_MS
          Minimum time between reports back to the server; strictly positive but much less than MIN_GENERATION_MS.
private  int percentCPU
          Target percent CPU usage (of all CPUs in host machine) in exclusive range ]1,100[, ie strictly positive.
private static boolean PLAYBACK_NO_NET
          If true then use playback calibration/thumbnail data rather than attempting to connect to the server.
private static boolean PLAYBACK_SAVE_DATA
          If true then save/record calibration data received from server.
private  boolean pleaseQuit
          Set to try to force main loop to quit ASAP, never set back to false.
(package private)  javax.jnlp.PersistenceService ps
          Handle on JWS persistence service; null if none.
private  java.util.concurrent.atomic.AtomicInteger scorersReported
          Number of Scorers reported back home (ignoring failures); never null, never negative.
private  java.lang.String serverHostname
          Server host name; never null.
(package private)  javax.jnlp.SingleInstanceService sis
          Handle on JWS singleton service; null if none.
private  java.lang.String tunnelURL
          Full URL for dedicated 'AH' tunnel on server; never null.
private  java.util.concurrent.ThreadPoolExecutor workerThreadPoolDiscardable
          Thread pool; reconfigurable at run-time; never null.
 
Constructor Summary
AHStandaloneMain(SimpleLoggerIF log)
          Create worker instance with all defaults and the supplied logger.
AHStandaloneMain(java.lang.String serverHostname, SimpleLoggerIF log, int percentCPU, int chunkMs)
          Create worker instance with the suppied logger and other parameters.
 
Method Summary
(package private)  void doWork()
          Simple core worker routine, usually runs until JVM terminates.
private  java.io.File getCacheDir()
          Get filesystem-based thumbnail/data cache directory, or null if none.
private  Tuple.Pair<java.util.Set<java.lang.String>,java.util.Map<java.lang.String,ScoreAndConf>> getCalibrationSet(java.lang.String tunnelURL, java.lang.String baseName)
          Get calibration data from server; never null but may be empty.
(package private)  int getCalibrationSetSize()
          Get size of current calibration set, or zero if none.
private  java.util.List<java.lang.String> getData(java.lang.String tunnelURL, java.lang.String dataType, java.lang.String q)
          Fetch specified ordered records from server; may be empty but never null.
(package private)  int getGeneration()
          Get generation number; strictly positive.
(package private)  int getGenTimeRemaining()
          Get time remaining for this generation; reset if a new/best Scorer is found.
(package private)  ScoreAndConf getLastSAC()
          Get score/confidence of last Scorer reported; never null.
(package private)  int getPopulationSize()
          Allow polling for population size; non-negative.
(package private)  int getScorersReported()
          Get number of Scorers reported back home; never negative.
(package private)  int getTargetPercentCPU()
          Get current target CPU load percentage in range ]1,100[.
static void main(java.lang.String[] args)
          Command-line start-up.
private static boolean sendNewBestScorer(java.lang.String tunnelURL, java.lang.String scorerNameAndParameters, SimpleLoggerIF log)
          Send the new Scorer back to the server.
(package private)  void setTargetPercentCPU(int pc)
          Set current target CPU load percentage in range ]1,100[.
 void shutdown()
          Try to shut down quickly and gracefully and with minimal loss of work.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

defaultLogger

public static final SimpleLoggerIF defaultLogger
Default logger: writes to stdout.


DEFAULT_SERVER

private static final java.lang.String DEFAULT_SERVER
Default server host name to connect back to; the generic/main host in this case.

See Also:
Constant Field Values

DEFAULT_CPU_PERCENT

public static final int DEFAULT_CPU_PERCENT
Default target fractional CPU usage (of entire host) in exclusive range ]1,100[, ie strictly positive. Generally much less than 100% to avoid straining a user system, eg if overclocked or undercooled, and to get reasonable computational return for energy used amortising the base power consumption of the host machine.

See Also:
Constant Field Values

DEFAULT_CPU_CHUNK_MS

public static final int DEFAULT_CPU_CHUNK_MS
Default target CPU work chunk in ms; strictly positive. A value from a few hundred milliseconds to a few tens of seconds probably keeps overheads to a reasonably low proportion of CPU time,] and allows slow methods such as minimisation a chance to work.

A sub-1s value may look less weird/lumpy on a user's CPU meter (given a typical 1s sampling on GUI performance meters).

See Also:
Constant Field Values

ALLOW_FILESYSTEM_TNCACHE

private static final boolean ALLOW_FILESYSTEM_TNCACHE
If true then attempt to use a primitive filesystem thumbnail/data cache where permitted. This will not be permitted in a JWS environment for example.

This may save a great deal of bandwidth avoiding refetching thumbnails.

The cache may also be prepopulated for stand-alone tests.

This cache is flat, ie contains no subdirectories, and will not be used unless already extant with appropriate permissions.

This may need to be periodically manually cleared of stale/old/bulk/corrupt data, and may become inefficient if it gains many entries.

See Also:
Constant Field Values

DEFAULT_TNCACHE_DIR

private static final java.lang.String DEFAULT_TNCACHE_DIR
Default directory in which cache thumbnail/playback data; always relative to pwd/cwd.

See Also:
Constant Field Values

PLAYBACK_SAVE_DATA

private static final boolean PLAYBACK_SAVE_DATA
If true then save/record calibration data received from server. Data is saved into a fixed directory where it can easily be retrieved for playback (no-network) mode.

Not viable/safe for JWS mode.

Should not be used (true) when PLAYBACK_NO_NET is true.

See Also:
Constant Field Values

PLAYBACK_NO_NET

private static final boolean PLAYBACK_NO_NET
If true then use playback calibration/thumbnail data rather than attempting to connect to the server. This is for stand-alone regression/performance/JVM testing with no network access.

See Also:
Constant Field Values

serverHostname

private final java.lang.String serverHostname
Server host name; never null.


log

private final SimpleLoggerIF log
Logger; never null.


percentCPU

private volatile int percentCPU
Target percent CPU usage (of all CPUs in host machine) in exclusive range ]1,100[, ie strictly positive.


chunkMs

private volatile int chunkMs
Target CPU work chunk in ms; strictly positive.


bs

final javax.jnlp.BasicService bs
Handle on JWS basic service; null if none. Package-visible so as to be directly usable by GUI classes.


ps

final javax.jnlp.PersistenceService ps
Handle on JWS persistence service; null if none. Package-visible so as to be directly usable by GUI classes.


fos

final javax.jnlp.FileOpenService fos
Handle on JWS file-open service; null if none. Package-visible so as to be directly usable by GUI classes.


sis

final javax.jnlp.SingleInstanceService sis
Handle on JWS singleton service; null if none. Package-visible so as to be directly usable by GUI classes.


exs

final javax.jnlp.ExtendedService exs
Handle on JWS extended service; null if none. Package-visible so as to be directly usable by GUI classes.


workerThreadPoolDiscardable

private final java.util.concurrent.ThreadPoolExecutor workerThreadPoolDiscardable
Thread pool; reconfigurable at run-time; never null.


lastFetchedCalibrationData

private volatile long lastFetchedCalibrationData
Last time we polled the server for calibration data. Initially zero (indicating "never").

Marked volatile for thread-safe lock-free access.


DATA_BLOCK_START

public static final java.lang.String DATA_BLOCK_START
Start sequence; we look for a line containing this to start our data.

See Also:
Constant Field Values

DATA_BLOCK_END

public static final java.lang.String DATA_BLOCK_END
End sequence; we look for a line containing this to start our data.

See Also:
Constant Field Values

GETDATA_METHOD

private static final java.lang.String GETDATA_METHOD
Method to use in getData() to connect to server (POST or GET). POST easier to distinguish from normal browser (human) traffic, but may not get through some proxies or firewalls.

See Also:
Constant Field Values

_submitLock

private static final java.lang.Object _submitLock
Lock used to serialise new/best Scorer submissions back to the server; never null.


tunnelURL

private final java.lang.String tunnelURL
Full URL for dedicated 'AH' tunnel on server; never null.


fakeTunnel

private final AHStandaloneMain.FakeTunnel fakeTunnel
Synthetic data pipeline tunnel back to server; never null.


cb

private final AHStandaloneMain.Callback cb
Callback object for reporting new/best Scorer; never null.


scorersReported

private final java.util.concurrent.atomic.AtomicInteger scorersReported
Number of Scorers reported back home (ignoring failures); never null, never negative.


lastSAC

private volatile ScoreAndConf lastSAC
Score/confidence of last Scorer reported; never null. Marked volatile for safe lock-free access.


genTimeRemaining

private volatile int genTimeRemaining
Time remaining for this generation; reset if a new/best Scorer is found. Marked volatile for safe lock-free access.


MIN_GENERATION_MS

public static final int MIN_GENERATION_MS
Minimum time (in ms) spent working on one generation; strictly positive. Setting a lower bound on generation time avoids wasting too much bandwidth on the client fetching calibraton data and maximises the chance of a client finding an 'unusual'/rare Scorer, but setting it too high risks wasting client CPU when no more progress can be made.

A value in the range of minutes to hours is probably appropriate.


MIN_SCORER_SERVER_REPORT_GAP_MS

public static final int MIN_SCORER_SERVER_REPORT_GAP_MS
Minimum time between reports back to the server; strictly positive but much less than MIN_GENERATION_MS. This avoids wasteful 'chatter' back to base, but ensures that we should always have time to flush our 'last' result back for a given generation.

Should be small enough to minimise any chance of significant work loss with unexpected shutdown.


pleaseQuit

private volatile boolean pleaseQuit
Set to try to force main loop to quit ASAP, never set back to false. Marked volatile for thread-safe lock-free access.

Constructor Detail

AHStandaloneMain

AHStandaloneMain(SimpleLoggerIF log)
Create worker instance with all defaults and the supplied logger. Does no work; just stores the parameters.

Package-visible to be exposed only to this package.


AHStandaloneMain

AHStandaloneMain(java.lang.String serverHostname,
                 SimpleLoggerIF log,
                 int percentCPU,
                 int chunkMs)
Create worker instance with the suppied logger and other parameters. Does no work; just stores the parameters.

Package-visible to be exposed only to this package.

Method Detail

main

public static void main(java.lang.String[] args)
Command-line start-up. Takes no arguments.

Writes any log/status information to stdout.

Defaults to take ~50% of available CPU.

Parameters:
args - an optional first argument is interpretted as serverhost[:port]

getCacheDir

private java.io.File getCacheDir()
Get filesystem-based thumbnail/data cache directory, or null if none.


getData

private java.util.List<java.lang.String> getData(java.lang.String tunnelURL,
                                                 java.lang.String dataType,
                                                 java.lang.String q)
                                          throws java.io.IOException
Fetch specified ordered records from server; may be empty but never null. Looks for first block of lines between , extracting each line starting with
  • and ending with
  • as a record.

    Parameters:
    q - if not null, part to pass as the generic (query) parameter (will be URL encoded)
    Throws:
    java.io.IOException

    getCalibrationSet

    private Tuple.Pair<java.util.Set<java.lang.String>,java.util.Map<java.lang.String,ScoreAndConf>> getCalibrationSet(java.lang.String tunnelURL,
                                                                                                                       java.lang.String baseName)
                                                                                                                throws java.io.IOException
    Get calibration data from server; never null but may be empty.

    Parameters:
    baseName - valid Scorer base name supported by current cache/population
    Returns:
    the set of full calibration exhibit names for the given Scorer base type, and the map from the short version of those names to their ScoreAndConf calibration/vote values
    Throws:
    java.io.IOException

    sendNewBestScorer

    private static boolean sendNewBestScorer(java.lang.String tunnelURL,
                                             java.lang.String scorerNameAndParameters,
                                             SimpleLoggerIF log)
    Send the new Scorer back to the server. We serialise these to never send back more than one at a time to avoid wasting server connection resources.

    Parameters:
    tunnelURL - the full URL for the tunnel servlet; never null
    scorerNameAndParameters - the Scorer description to send to the server
    Returns:
    true if we seem to have sent the data successfully to the server

    getTargetPercentCPU

    int getTargetPercentCPU()
    Get current target CPU load percentage in range ]1,100[.


    setTargetPercentCPU

    void setTargetPercentCPU(int pc)
    Set current target CPU load percentage in range ]1,100[. An out-of-range value is coerced into range.

    We also adjust the CPU chunk size for better scheduling and CPU behaviour at extremes.

    Parameters:
    pc - target percent CPU time in the range 1 to 100.

    getGeneration

    int getGeneration()
    Get generation number; strictly positive.


    getPopulationSize

    int getPopulationSize()
    Allow polling for population size; non-negative.


    getCalibrationSetSize

    int getCalibrationSetSize()
    Get size of current calibration set, or zero if none.


    getScorersReported

    final int getScorersReported()
    Get number of Scorers reported back home; never negative.


    getLastSAC

    ScoreAndConf getLastSAC()
    Get score/confidence of last Scorer reported; never null.


    getGenTimeRemaining

    int getGenTimeRemaining()
    Get time remaining for this generation; reset if a new/best Scorer is found.


    doWork

    void doWork()
    Simple core worker routine, usually runs until JVM terminates. Creates a communication tunnel back home, then runs whatever work needs doing.

    Will quit immediately if it cannot "call home" when it starts up. Thereafter it will retry to overcome errors as necessary.

    Not thread-safe (ie only one thread should call this at once for this instance).

    Package-visible to be exposed only to this package.


    shutdown

    public void shutdown()
    Try to shut down quickly and gracefully and with minimal loss of work. We try to flush any pending results back to the server.


    DHD Multimedia Gallery V1.50.55

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