Skip to content

Commit 6ebd546

Browse files
author
Nathan Lee
committed
Added app lifecycle hooks accessible via decorators.
1 parent 2c0d406 commit 6ebd546

File tree

3 files changed

+50
-12
lines changed

3 files changed

+50
-12
lines changed

pyrunner/core/constants.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,17 @@
4444
from pathlib import Path
4545
4646
def main():
47-
pr = PyRunner()
47+
app = PyRunner()
4848
4949
# Assign default config and .lst file
50-
pr.source_config_file(Path('{}/app_profile'.format(pr.config['config_dir'])))
51-
pr.load_from_file(Path('{}/{}.lst'.format(pr.config['config_dir'], pr.config['app_name'])))
50+
app.source_config_file(Path('{}/app_profile'.format(app.config['config_dir'])))
51+
app.load_from_file(Path('{}/{}.lst'.format(app.config['config_dir'], app.config['app_name'])))
5252
5353
# Parse command line args
54-
pr.parse_args()
54+
app.parse_args()
5555
5656
# Initiate job
57-
exit_status = pr.execute()
57+
exit_status = app.execute()
5858
5959
# Ensure job exit status is passed to the caller
6060
sys.exit(exit_status)

pyrunner/core/pyrunner.py

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ def __init__(self, **kwargs):
5757
'exec_to_id' : None
5858
}
5959

60+
self._on_restart_func = None
61+
self._on_success_func = None
62+
self._on_fail_func = None
63+
self._on_exit_func = None
64+
6065
# Config wiring
6166
self.source_config_file = self.config.source_config_file
6267

@@ -117,6 +122,15 @@ def plugin_notification(self, obj):
117122
if not isinstance(obj, notification.Notification): raise Exception('Notification plugin must implement the Notification interface')
118123
self.notification = obj
119124

125+
def on_restart(self, func):
126+
self._on_restart_func = func
127+
def on_success(self, func):
128+
self._on_success_func = func
129+
def on_fail(self, func):
130+
self._on_fail_func = func
131+
def on_exit(self, func):
132+
self._on_exit_func = func
133+
120134
def execute(self):
121135
return self.run()
122136
def run(self):
@@ -126,6 +140,7 @@ def run(self):
126140
# Initialize NodeRegister
127141
if self._init_params['restart']:
128142
if not self.load_last_failed():
143+
self._init_params['restart'] = False
129144
self.load_proc_list_file(self._init_params['proc_file'])
130145
else:
131146
self.load_proc_list_file(self._init_params['proc_file'])
@@ -142,24 +157,48 @@ def run(self):
142157
if self._init_params['exec_to_id'] is not None:
143158
self.exec_to(self._init_params['exec_to_id'])
144159

160+
# App lifecycle - RESTART
161+
if self._init_params['restart'] and self._on_restart_func:
162+
self._on_restart_func()
163+
145164
self.config['app_start_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
146165

166+
# Prepare engine
147167
self.engine.config = self.config
148168
self.engine.register = self.register
149169
self.engine.save_state_func = self.save_state
150170

171+
# Short circuit for a dryrun
151172
if self.config['dryrun']:
152173
self.print_documentation()
153174
return 0
154175

176+
# Fire up engine
155177
print('Executing PyRunner App: {}'.format(self.config['app_name']))
156178
retcode = self.engine.initiate()
157179

158-
if retcode == 0 and not self.config['email_on_success']:
159-
print('Skipping Email Notification: Property "email_on_success" is set to FALSE.')
160-
elif retcode != 0 and not self.config['email_on_fail']:
161-
print('Skipping Email Notification: Property "email_on_fail" is set to FALSE.')
180+
emit_notification = True
181+
182+
# # App lifecycle - SUCCESS
183+
if retcode == 0:
184+
if self._on_success_func:
185+
self._on_success_func()
186+
if not self.config['email_on_succss']:
187+
print('Skipping Email Notification: Property "email_on_success" is set to FALSE.')
188+
emit_notification = False
189+
# # App lifecycle - FAIL
162190
else:
191+
if self._on_fail_func:
192+
self._on_fail_func()
193+
if not self.config['email_on_fail']:
194+
print('Skipping Email Notification: Property "email_on_fail" is set to FALSE.')
195+
emit_notification = False
196+
197+
# App lifecycle - EXIT
198+
if self._on_exit_func:
199+
self._on_exit_func()
200+
201+
if emit_notification:
163202
self.notification.emit_notification(self.config, self.register)
164203

165204
if not self.config['nozip']:
@@ -325,8 +364,7 @@ def parse_args(self):
325364
elif opt in ['-n', '--max-procs']:
326365
self.config['max_procs'] = int(arg)
327366
elif opt in ['-r', '--restart']:
328-
if os.path.isfile(self.config.ctllog_file):
329-
self._init_params['restart'] = True
367+
self._init_params['restart'] = True
330368
elif opt in ['-x', '--exec-only']:
331369
self._init_params['exec_only_list'] = [ int(id) for id in arg.split(',') ]
332370
elif opt in ['-N', '--norun']:

pyrunner/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '4.0.3'
1+
__version__ = '4.1.0'

0 commit comments

Comments
 (0)