-
Notifications
You must be signed in to change notification settings - Fork 0
/
aptaskd.py
executable file
·182 lines (136 loc) · 4.41 KB
/
aptaskd.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/env python
"""
Asynchronous Parallel Task Execution Daemon Script
"""
__version__ = '0.0.0'
import multiprocessing
import os
import signal
import sys
import time
import configuration
import log
import manager
import net
#=============================================================================
_is_running = False # daemon control flag
#=============================================================================
def signal_handler( signal_number, frame ):
"""
Empty signal handler (for now)
@param signal_number
The signal number from the OS interrupt
@param frame The frame
"""
# stop the daemon
stop()
#=============================================================================
def start( config ):
"""
Daemon function allows this to be used from a wrapper script.
@param config Application configuration object
@return Exit code (0 = normal)
"""
# global control flag
global _is_running
# add tasks directory to import path list
sys.path.append( config.get_path( 'tasks' ) )
# initialize the logging facility
logger = log.Log( config.get_log_file(), config.loglevel )
logger.append_message( 'initializing daemon' )
# create the network server control and communications pipe
( p_pipe, c_pipe ) = multiprocessing.Pipe( True )
# create network server in its own process
netd = multiprocessing.Process(
target = net.net,
args = ( c_pipe, config.get_address() ),
name = 'aptasknetd'
)
# create and start the task manager
man = manager.Manager( config, logger )
man.start()
# set running flag
_is_running = True
# start the network server process
netd.start()
# enter daemon loop
while _is_running == True:
# check for requests from netd
if p_pipe.poll() == True:
# get message data and send to message handler
message = p_pipe.recv()
message.data = man.handle_request( message.data )
p_pipe.send( message )
# allow manager to process worker queues
man.process()
# poll interval (may not be needed, or could be adaptive)
#if _is_running == True:
# time.sleep( 0.005 )
# shut down task manager
man.stop()
# shut down network server
p_pipe.send( net.QUIT )
netd.join()
# indicate shut down and close log
logger.append_message( 'shutting down daemon' )
logger.close()
# return exit code
return 0
#=============================================================================
def stop():
"""
Stops the daemon function.
"""
# global control flag
global _is_running
# exit the daemon loop at its next convenience
_is_running = False
#=============================================================================
def main( argv ):
"""
Script execution entry point
@param argv Arguments passed to the script
@return Exit code (0 = success)
"""
# imports when using this as a script
import argparse
import json
# install some signal handlers to override what Python installed
signal.signal( signal.SIGTERM, signal_handler )
signal.signal( signal.SIGINT, signal_handler )
# create and configure an argument parser
parser = argparse.ArgumentParser(
description = 'Asynchronous Parallel Task Execution Daemon Script'
)
parser.add_argument(
'-c',
'--config',
default = 'aptaskd.json',
help = 'Load configuration file from this location.'
)
parser.add_argument(
'-v',
'--version',
default = False,
help = 'Display script version.',
action = 'store_true'
)
# parse the arguments
args = parser.parse_args( argv[ 1 : ] )
# check for version request
if args.version == True:
print 'Version', __version__
return 0
# load configuration
config = configuration.load_configuration( args.config )
# check configuration
if config is None:
print 'invalid configuration'
return -1
# run the daemon until shut down
exit_code = start( config )
# return exit code
return exit_code
#=============================================================================
if __name__ == "__main__":
sys.exit( main( sys.argv ) )