DaemonApp

Extensible class to do all the common task needed for an application to run.

This class also implements its own extension interface, so it's easy to write an application using the hooks in extensions without having to write a separate extension. The order of this extension is 0, establishing a reference order for all the other extensions. Extensions that should be executed before the application hooks should have a negative order, while extensions that have to be executed after the application hooks should have a positive order value.

The common usage is to derive from Application and override the run() method. Optionally you can override the extensions methods too.

abstract
class DaemonApp : Application , IArgumentsExtExtension , IConfigExtExtension , ILogExtExtension , ISignalExtExtension {}

Constructors

this
this(istring name, istring desc, VersionInfo ver, OptionalSettings settings)

This constructor only sets up the internal state of the class, but does not call any extension or user code.

Members

Aliases

Arguments
alias Arguments = ocean.text.Arguments.Arguments
Undocumented in source.
ConfigParser
alias ConfigParser = ocean.util.config.ConfigParser.ConfigParser
Undocumented in source.

Functions

collectGCStats
void collectGCStats(Collector prometheus_collector)

Collects GC stats for incoming prometheus' requests. Should be sent, as a callback, to the CollectorRegistry instance used in prometheus request listener.

collectSystemStats
void collectSystemStats(Collector prometheus_collector)

Collects CPU and memory stats for incoming prometheus' requests. Should be sent, as a callback, to the CollectorRegistry instance used in prometheus request listener.

exit
void exit(int status, istring msg)
void exit(int status, istring msg, Logger logger)

Exit cleanly from the application, passing the specified return code to the OS and optionally printing the specified message to the console.

filterConfigFiles
istring[] filterConfigFiles(IApplication app, ConfigParser config, istring[] files)

IConfigExtExtension methods dummy implementation.

onSignal
void onSignal(int signum)

ISignalExtExtension method default implementation.

onStatsTimer
void onStatsTimer()

Called by the timer extension when the stats period fires. By default does nothing, but should be overridden to write the required stats.

postConfigureLoggers
void postConfigureLoggers(IApplication app, ConfigParser config, bool loose_config_parsing, bool use_insert_appender)

ILogExtExtension methods dummy implementation.

preConfigureLoggers
void preConfigureLoggers(IApplication app, ConfigParser config, bool loose_config_parsing, bool use_insert_appender)

ILogExtExtension methods dummy implementation.

preParseConfig
void preParseConfig(IApplication app, ConfigParser config)

IConfigExtExtension methods dummy implementation.

preValidateArgs
void preValidateArgs(IApplication app, Arguments args)
processArgs
void processArgs(IApplication app, Arguments args)

IArgumentsExtExtension methods dummy implementation.

processConfig
void processConfig(IApplication app, ConfigParser config)

IConfigExtExtension methods dummy implementation.

reportGCStats
void reportGCStats()

Collects GC stats and reports them to stats log. Should be called periodically (inside onStatsTimer).

reportSystemStats
void reportSystemStats()

Collects CPU and memory stats and reports it to stats log. Should be called periodically (inside onStatsTimer).

run
int run(istring[] args)

Run implementation that forwards to the abstract run(Arguments, ConfigParser).

run
int run(Arguments args, ConfigParser config)

This method must be implemented by subclasses to do the actual application work.

setupArgs
void setupArgs(IApplication app, Arguments args)

IArgumentsExtExtension methods dummy implementation.

startEventHandling
void startEventHandling(EpollSelectDispatcher epoll)

This method must be called in order for signal and timer event handling to start being processed. As it registers clients (the stats timer and signal handler) with epoll which will always reregister themselves after firing, you should call this method when you are about to start your application's main event loop.

validateArgs
cstring validateArgs(IApplication app, Arguments args)

IArgumentsExtExtension methods dummy implementation.

Structs

OptionalSettings
struct OptionalSettings

Struct containing optional constructor arguments. There are enough of these that handling them as default arguments to the ctor is cumbersome.

Variables

args
Arguments args;

Command line arguments used by the application.

args_ext
ArgumentsExt args_ext;

Command line arguments extension used by the application.

config
ConfigParser config;

Configuration parser to use to parse the configuration files.

config_ext
ConfigExt config_ext;

Configuration parsing extension instance.

log_ext
LogExt log_ext;

Logging extension instance.

pidlock_ext
PidLockExt pidlock_ext;

PidLock extension. Tries to create and lock the pid lock file (if specified in the config), ensuring that only one application instance per pidlock may exist.

reopenable_files_ext
ReopenableFilesExt reopenable_files_ext;

Reopenable files extension. Hooks into the stats, log, and signal extentions, and automatically reopens logfiles upon receipt of the SIGHUP signal (presumably sent from logrotate).

signal_ext
SignalExt signal_ext;

Signal handler extension. Directs registered signals to the onSignal() method.

stats_ext
StatsExt stats_ext;

Stats log extension -- TODO auto configured or what? Why public? getter for StatsLog instance?

task_ext
TaskExt task_ext;

Extension to start run method inside a task.

timer_ext
TimerExt timer_ext;

Timer handler extension.

unix_socket_ext
UnixSocketExt unix_socket_ext;

Unix socket extension to register commands for the application to respond to.

ver
VersionInfo ver;

Version information.

ver_ext
VersionArgsExt ver_ext;

Version information extension.

Inherited Members

From Application

__anonymous
mixin ExtensibleClassMixin!(IApplicationExtension)

Adds a list of extensions (this.extensions) and methods to handle them. See ExtensibleClassMixin documentation for details.

Application
alias Application = .Application

Alias of Application, for use by sub-classes without needing to import ocean.util.app.Application.

desc
istring desc;

Short description of the application.

args
istring[] args;

Command line arguments passed to the application.

status
int status;

Application exit status code.

name
istring name()
exit
void exit(int status, istring msg)

Exit cleanly from the application.

main
int main(istring[] args)

Runs the application.

printExitException
void printExitException(ExitException e)

Prints the message in an ExitException.

run
int run(istring[] args)

Do the actual application work.

order
int order()

Default application extension order.

preRun
void preRun(IApplication app, istring[] args)

IApplicationExtension methods dummy implementation.

postRun
void postRun(IApplication app, istring[] args, int status)
Undocumented in source. Be warned that the author may not have intended to support it.
atExit
void atExit(IApplication app, istring[] args, int status, ExitException exception)
Undocumented in source. Be warned that the author may not have intended to support it.
onExitException
ExitException onExitException(IApplication app, istring[] args, ExitException exception)
Undocumented in source. Be warned that the author may not have intended to support it.

From IArgumentsExtExtension

setupArgs
void setupArgs(IApplication app, Arguments args)

Function executed when command line arguments are set up (before parsing).

preValidateArgs
void preValidateArgs(IApplication app, Arguments args)

Function executed after parsing of command line args (whether the basic parsing failed or succeeded) but before the call to validateArgs().

validateArgs
cstring validateArgs(IApplication app, Arguments args)

Function executed after parsing the command line arguments.

processArgs
void processArgs(IApplication app, Arguments args)

Function executed after (successfully) validating the command line arguments.

From IConfigExtExtension

preParseConfig
void preParseConfig(IApplication app, ConfigParser config)

Function executed before the configuration files are parsed.

filterConfigFiles
istring[] filterConfigFiles(IApplication app, ConfigParser config, istring[] files)

Function to filter the list of configuration files to parse.

processConfig
void processConfig(IApplication app, ConfigParser config)

Function executed after the configuration files are parsed.

From ILogExtExtension

preConfigureLoggers
void preConfigureLoggers(IApplication app, ConfigParser config, bool loose_config_parsing, bool use_insert_appender)

Function executed before the loggers are configured.

postConfigureLoggers
void postConfigureLoggers(IApplication app, ConfigParser config, bool loose_config_parsing, bool use_insert_appender)

Function executed after the loggers are configured.

From ISignalExtExtension

onSignal
void onSignal(int signum)

Called when the SignalExt is notified of a signal.

Examples

import ocean.util.app.Application;
import ocean.io.Stdout;

class MyApp : Application
{
    this ( )
    {
        super("myapp", "A test application");
    }
    protected override void preRun ( Application app, istring[] args )
    {
        if ( args.length < 4 )
        {
            this.exit(1, "Too few arguments");
        }
    }
    protected override int run ( istring[] args )
    {
        Stdout.formatln("Application is running!");

        return 0;
    }
    protected override void postRun ( Application app, istring[] args,
            int status )
    {
        Stdout.formatln("Application returned {}", status);

    }
}

int main(istring[] args)
{
    auto app = new MyApp;
    return app.main(args);
}

As seen in the example, this class also provides a clean way to exit an application from anywhere in the program, the exit() method.

The main() method is the real only needed public API, and the one calling all the extension code. The real application call must be in the run() method, which is abstract, and mandatory to implement.

The full power and usefulness of this class comes from extensions though.

1 /***************************************************************************
2 
3     Example daemon application class.
4 
5 ***************************************************************************/
6 
7 class MyApp : DaemonApp
8 {
9     import core.sys.posix.signal: SIGINT, SIGTERM;
10 
11     import ocean.io.select.EpollSelectDispatcher;
12 
13     this ( )
14     {
15 
16         // The name of your app and a short description of what it does.
17         istring name = "my_app";
18         istring desc = "Dummy app for unittest.";
19 
20         // The version info for your app. Normally you get this by importing
21         // Version and passing the AA which contains the version info
22         // (called versionInfo) to DaemonApp's constructor.
23         auto ver = VersionInfo.init;
24 
25         // You may also pass an instance of OptionalSettings to DaemonApp's
26         // constructor, to specify non-mandatory options. In this example,
27         // we specify the help text and some signals that we want to handle.
28         DaemonApp.OptionalSettings settings;
29         settings.help = "Actually, this program does nothing. Sorry!";
30         settings.signals = [SIGINT, SIGTERM];
31 
32         // Call the super class' ctor.
33         super(name, desc, ver, settings);
34     }
35 
36     // Called after arguments and config file parsing.
37     override protected int run ( Arguments args, ConfigParser config )
38     {
39         // In order for signal and timer handling to be processed, you must
40         // call this method. This registers one or more clients with epoll.
41         this.startEventHandling(new EpollSelectDispatcher);
42 
43         // Application main logic. Usually you would call the epoll event
44         // loop here.
45 
46         return 0; // return code to OS
47     }
48 
49     // Handle those signals we were interested in
50     //
51     // Note that DaemonApp provides default `onSignal` implementation
52     // that handles `SIGTERM` and calls `theScheduler.shutdown` upon
53     // receiving the signal. This results in clean termination but may also
54     // cause some in-progress data loss from killed tasks - any application
55     // that must never loose data needs to implement own handler.
56     override public void onSignal ( int signal )
57     {
58         switch ( signal )
59         {
60             case SIGINT:
61             case SIGTERM:
62                 // Termination logic.
63                 break;
64             default:
65         }
66     }
67 
68     // Handle stats output.
69     override protected void onStatsTimer ( )
70     {
71         this.reportSystemStats();
72         this.reportGCStats();
73         struct Treasure
74         {
75             int copper, silver, gold;
76         }
77         Treasure loot;
78         this.stats_ext.stats_log.add(loot);
79         this.stats_ext.stats_log.flush();
80     }
81 }
82 
83 /***************************************************************************
84 
85     Your application's main() function should look something like this.
86     (This function is not called here as we don't want to actually run the
87     application in this unittest -- it will fail due to the lack of properly
88     configured etc/ and log/ directories.)
89 
90 ***************************************************************************/
91 
92 int main ( istring[] cl_args )
93 {
94     // Instantiate an instance of your app class.
95     auto my_app = new MyApp;
96 
97     // Pass the raw command line arguments to its main function.
98     auto ret = my_app.main(cl_args);
99 
100     // Return ret to the OS.
101     return ret;
102 }

Meta