This constructor only sets up the internal state of the class, but does not call any extension or user code.
Collects GC stats for incoming prometheus' requests. Should be sent, as a callback, to the CollectorRegistry instance used in prometheus request listener.
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 cleanly from the application, passing the specified return code to the OS and optionally printing the specified message to the console.
IConfigExtExtension methods dummy implementation.
ISignalExtExtension method default implementation.
Called by the timer extension when the stats period fires. By default does nothing, but should be overridden to write the required stats.
ILogExtExtension methods dummy implementation.
ILogExtExtension methods dummy implementation.
IConfigExtExtension methods dummy implementation.
IArgumentsExtExtension methods dummy implementation.
IConfigExtExtension methods dummy implementation.
Collects GC stats and reports them to stats log. Should be called periodically (inside onStatsTimer).
Collects CPU and memory stats and reports it to stats log. Should be called periodically (inside onStatsTimer).
Run implementation that forwards to the abstract run(Arguments, ConfigParser).
This method must be implemented by subclasses to do the actual application work.
IArgumentsExtExtension methods dummy implementation.
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.
IArgumentsExtExtension methods dummy implementation.
Struct containing optional constructor arguments. There are enough of these that handling them as default arguments to the ctor is cumbersome.
Command line arguments used by the application.
Command line arguments extension used by the application.
Configuration parser to use to parse the configuration files.
Configuration parsing extension instance.
Logging extension instance.
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 extension. Hooks into the stats, log, and signal extentions, and automatically reopens logfiles upon receipt of the SIGHUP signal (presumably sent from logrotate).
Signal handler extension. Directs registered signals to the onSignal() method.
Stats log extension -- TODO auto configured or what? Why public? getter for StatsLog instance?
Extension to start run method inside a task.
Timer handler extension.
Unix socket extension to register commands for the application to respond to.
Version information.
Version information extension.
Adds a list of extensions (this.extensions) and methods to handle them. See ExtensibleClassMixin documentation for details.
Alias of Application, for use by sub-classes without needing to import ocean.util.app.Application.
Short description of the application.
Command line arguments passed to the application.
Application exit status code.
Exit cleanly from the application.
Runs the application.
Prints the message in an ExitException.
Do the actual application work.
Default application extension order.
IApplicationExtension methods dummy implementation.
Function executed when command line arguments are set up (before parsing).
Function executed after parsing of command line args (whether the basic parsing failed or succeeded) but before the call to validateArgs().
Function executed after parsing the command line arguments.
Function executed after (successfully) validating the command line arguments.
Function executed before the configuration files are parsed.
Function to filter the list of configuration files to parse.
Function executed after the configuration files are parsed.
Function executed before the loggers are configured.
Function executed after the loggers are configured.
Called when the SignalExt is notified of a signal.
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 }
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.