1 // This file is written in D programming language
2 /**
3 *   The example shows how to send signals to daemons created by
4 *   daemonize.
5 *
6 *   Copyright: © 2014 Anton Gushcha
7 *   License: Subject to the terms of the MIT license, as written in the included LICENSE file.
8 *   Authors: NCrashed <ncrashed@gmail.com>
9 */
10 module example02;
11 
12 static if( __VERSION__ < 2075) import std.datetime;
13 else import core.time;
14 
15 import daemonize.d;
16 
17 // Describing custom signals
18 enum RotateLogSignal = "RotateLog".customSignal;
19 enum DoSomethingSignal = "DoSomething".customSignal;
20 
21 version(DaemonServer)
22 {
23     // Full description for daemon side
24     alias daemon = Daemon!(
25         "DaemonizeExample2",
26         
27         KeyValueList!(
28             Composition!(Signal.Terminate, Signal.Quit, Signal.Shutdown, Signal.Stop), (logger)
29             {
30                 logger.logInfo("Exiting...");
31                 return false;
32             },
33             Signal.HangUp, (logger)
34             {
35                 logger.logInfo("Hello World!");
36                 return true;
37             },
38             RotateLogSignal, (logger)
39             {
40                 logger.logInfo("Rotating log!");
41                 logger.reload;
42                 return true;
43             },
44             DoSomethingSignal, (logger)
45             {
46                 logger.logInfo("Doing something...");
47                 return true;
48             }
49         ),
50 
51         (logger, shouldExit)
52         {
53             // will stop the daemon in 5 minutes
54             static if( __VERSION__ < 2075 )
55             {
56                 auto time = Clock.currSystemTick + cast(TickDuration)5.dur!"minutes";
57                 alias currTime = Clock.currSystemTick;
58             }
59             else
60             {
61                 auto time = MonoTime.currTime + 5.dur!"minutes";
62                 alias currTime = MonoTime.currTime;
63             }
64             while(!shouldExit() && time > currTime) {  }
65             logger.logInfo("Exiting main function!");
66             
67             return 0;
68         }
69     );
70     
71     int main()
72     {
73         // For windows is important to use absolute path for logging
74         version(Windows) string logFilePath = "C:\\logfile.log";
75         else string logFilePath = "logfile.log";
76 
77         auto logger = new shared DloggLogger(logFilePath);
78         return buildDaemon!daemon.run(logger);
79     }
80 }
81 version(DaemonClient)
82 {
83     import core.thread;
84     import core.time;
85     
86     // For client you don't need full description of the daemon
87     // the truncated description consists only of name and a list of
88     // supported signals
89     alias client = DaemonClient!(
90         "DaemonizeExample2",
91         Composition!(Signal.Terminate, Signal.Quit, Signal.Shutdown, Signal.Stop),
92         Signal.HangUp,
93         RotateLogSignal,
94         DoSomethingSignal
95     );
96     
97     void main()
98     {
99     	auto logger = new shared DloggLogger("client.log");
100 
101     	alias daemon = buildDaemon!client;
102     	alias send = daemon.sendSignal;
103     	alias uninstall = daemon.uninstall;
104     	
105         send(logger, Signal.HangUp); 
106         Thread.sleep(50.dur!"msecs");
107         send(logger, RotateLogSignal); 
108         Thread.sleep(50.dur!"msecs");
109         send(logger, DoSomethingSignal);         
110         Thread.sleep(50.dur!"msecs");
111         send(logger, Signal.Terminate);
112         
113         // For windows services are remain in SC manager until uninstalled manually
114         version(Windows)
115         {
116         	Thread.sleep(500.dur!"msecs");
117         	uninstall(logger);
118     	}
119     }
120 }