Skip to content

Commit 8c7dee3

Browse files
authored
Merge pull request #11 from Comcast/develop
v5
2 parents f509395 + 7b5eea6 commit 8c7dee3

11 files changed

Lines changed: 125 additions & 286 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# python-batch-runner
2+
[![Documentation Status](https://readthedocs.org/projects/python-batch-runner/badge/?version=latest)](https://python-batch-runner.readthedocs.io/en/latest/?badge=latest)
3+
24
For more complete documentation, please see: https://python-batch-runner.readthedocs.io/
35

46
python-batch-runner is a microframework to assist with building small to medium scale batch applications without needing to build the scaffolding from scratch.

pyrunner/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def setup():
127127
app_profile.write('export APP_EXEC_TIMESTAMP=$(date +"%Y%m%d_%H%M%S")\n\n')
128128
app_profile.write('export APP_LOG_DIR="${APP_ROOT_LOG_DIR}/${DATE}"\n\n')
129129
app_profile.write('if [ ! -e ${APP_LOG_DIR} ]; then mkdir -p ${APP_LOG_DIR}; fi\n')
130-
app_profile.write('if [ ! -e ${APP_TEMP_DIR} ]; then mkdir ${APP_TEMP_DIR}; fi\n')
130+
app_profile.write('if [ ! -e ${APP_TEMP_DIR} ]; then mkdir -p ${APP_TEMP_DIR}; fi\n')
131131

132132
print('Creating Blank Process List File: {}/config/{}.lst'.format(app_root, app_name))
133133
with open('{}/config/{}.lst'.format(app_root, app_name), 'w') as lst_file:

pyrunner/core/constants.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@
2828

2929
EXECUTION_TIMESTAMP = datetime.now().strftime("%Y%m%d_%H%M%S")
3030

31-
MODE_SHELL = 'SHELL'
3231
MODE_PYTHON = 'PYTHON'
33-
34-
HEADER_SHELL = '#{}\n#ID|PARENT_IDS|MAX_ATTEMPTS|RETRY_WAIT_TIME|PROCESS_NAME|SHELL_COMMAND|LOGFILE'.format(MODE_SHELL)
3532
HEADER_PYTHON = '#{}\n#ID|PARENT_IDS|MAX_ATTEMPTS|RETRY_WAIT_TIME|PROCESS_NAME|MODULE_NAME|WORKER_NAME|ARGUMENTS|LOGFILE'.format(MODE_PYTHON)
3633

3734
ROOT_NODE_NAME = 'PyRunnerRootNode'
@@ -40,7 +37,6 @@
4037
4138
import os, sys
4239
from pyrunner import PyRunner
43-
from pathlib import Path
4440
4541
# Determine absolute path of this file's parent directory at runtime
4642
abs_dir_path = os.path.dirname(os.path.realpath(__file__))

pyrunner/core/engine.py

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ def initiate(self, **kwargs):
7272
self.start_time = time.time()
7373
wait_interval = 1.0/self.config['tickrate'] if self.config['tickrate'] >= 1 else 0
7474
last_save = 0
75-
ab_code = 0
7675

7776
if not self.register: raise RuntimeError('NodeRegister has not been initialized!')
7877

@@ -120,7 +119,7 @@ def initiate(self, **kwargs):
120119
if p.id >= 0 and p not in self.register.completed_nodes.union(self.register.norun_nodes):
121120
runnable = False
122121
break
123-
if runnable:
122+
if runnable and node.is_runnable():
124123
self.register.pending_nodes.remove(node)
125124
node.context = self.context
126125
node.execute()
@@ -147,7 +146,6 @@ def initiate(self, **kwargs):
147146
print('\nKeyboard Interrupt Received')
148147
print('\nCancelling Execution')
149148
self._abort_all_workers()
150-
self.save_state_func(False, True)
151149
return -1
152150

153151
# App lifecycle - SUCCESS
@@ -164,7 +162,7 @@ def initiate(self, **kwargs):
164162
self._on_destroy_func()
165163

166164
if not kwargs.get('silent'):
167-
self._print_final_state(ab_code)
165+
self._print_final_state()
168166

169167
if not self.config['test_mode'] and self.save_state_func:
170168
self.save_state_func()
@@ -173,10 +171,12 @@ def initiate(self, **kwargs):
173171

174172
def _abort_all_workers(self):
175173
for node in self.register.running_nodes.copy():
176-
node.terminate()
174+
node.terminate('Keyboard Interrupt (SIGINT) received. Terminating Worker and exiting.')
177175
self.register.running_nodes.remove(node)
178176
self.register.aborted_nodes.add(node)
179177
self.register.set_children_defaulted(node)
178+
self.save_state_func(False, True)
179+
self._print_final_state(True)
180180

181181
def _print_current_state(self):
182182
elapsed = time.time() - self.start_time
@@ -205,39 +205,42 @@ def _print_current_state(self):
205205

206206
return
207207

208-
def _print_final_state(self, ab_code=0):
208+
def _print_final_state(self, aborted=False):
209209
print('\nCompleted in {:0.2f} seconds\n'.format(time.time() - self.start_time))
210210

211-
if ab_code > 0:
211+
if aborted:
212212
print('Final Status: ABORTED\n')
213+
print('Aborted Processes:\n')
214+
215+
for n in self.register.aborted_nodes:
216+
self._print_node_info(n, self.config['dump_logs'])
217+
213218
elif len(self.register.failed_nodes) + len(self.register.defaulted_nodes):
214219
print('Final Status: FAILURE\n')
215220
print('Failed Processes:\n')
216221

217222
for n in self.register.failed_nodes:
218-
print('ID: {}'.format(n.id))
219-
print('Name: {}'.format(n.name))
220-
print('Module: {}'.format(n.module))
221-
print('Worker: {}'.format(n.worker))
222-
print('Arguments: {}'.format(n.arguments))
223-
print('Log File: {}\n'.format(n.logfile))
224-
225-
if self.config['dump_logs']:
226-
print('DUMPING FAILURE LOGS\n')
227-
228-
for n in self.register.failed_nodes:
229-
print('############################################################################')
230-
print('# ID: {}'.format(n.id))
231-
print('# Name: {}'.format(n.name))
232-
print('# Module: {}'.format(n.module))
233-
print('# Worker: {}'.format(n.worker))
234-
print('# Arguments: {}'.format(n.arguments))
235-
print('# Log File: {}'.format(n.logfile))
236-
with open(n.logfile, 'r') as f:
237-
for line in f:
238-
print(line, end='')
223+
self._print_node_info(n, self.config['dump_logs'])
239224

240225
else:
241226
print('Final Status: SUCCESS\n')
242227

243-
return
228+
return
229+
230+
def _print_node_info(self, n, dump_logs=False):
231+
if dump_logs:
232+
print('############################################################################')
233+
234+
print('# ID: {}'.format(n.id))
235+
print('# Name: {}'.format(n.name))
236+
print('# Module: {}'.format(n.module))
237+
print('# Worker: {}'.format(n.worker))
238+
print('# Arguments: {}'.format(n.arguments))
239+
print('# Log File: {}'.format(n.logfile))
240+
241+
if dump_logs:
242+
with open(n.logfile, 'r') as f:
243+
for line in f:
244+
print(line, end='')
245+
246+
print('')

0 commit comments

Comments
 (0)