switch from Step.run() recursion to Step.run()-in-a-loop to avoid too-deep call stacks

master
Yves G 2018-01-31 15:13:03 +01:00 committed by Y
parent 14bda0a09b
commit dea4b5a016
5 changed files with 15 additions and 14 deletions

View File

@ -2,5 +2,4 @@
* Improve documentation, especially on the contents of `pyruse.json`. * Improve documentation, especially on the contents of `pyruse.json`.
* Maybe switch from storing the daily journal in a file, to storing it in a database. * Maybe switch from storing the daily journal in a file, to storing it in a database.
* Maybe switch from Step.run() recursion to Step.run()-in-a-loop to avoid too-deep call stacks.
* Eventually make the code more elegant, as I learn more about Python… * Eventually make the code more elegant, as I learn more about Python…

View File

@ -36,8 +36,7 @@ class Filter(Step):
except Exception as e: except Exception as e:
nextStep = self.altStep nextStep = self.altStep
log.error("Error while executing %s: %s." % (type(self), str(e))) log.error("Error while executing %s: %s." % (type(self), str(e)))
if nextStep: return nextStep
nextStep.run(entry)
class Action(Step): class Action(Step):
def __init__(self): def __init__(self):
@ -54,5 +53,4 @@ class Action(Step):
except Exception as e: except Exception as e:
nextStep = None nextStep = None
log.error("Error while executing %s: %s." % (type(self), str(e))) log.error("Error while executing %s: %s." % (type(self), str(e)))
if nextStep: return nextStep
nextStep.run(entry)

View File

@ -17,7 +17,7 @@ def _setPyrusePaths():
sys.path.insert(1, p) sys.path.insert(1, p)
PYRUSE_PATHS.insert(0, os.curdir) PYRUSE_PATHS.insert(0, os.curdir)
def _doForEachJournalEntry(fct): def _doForEachJournalEntry(workflow):
j = journal.Reader(journal.SYSTEM_ONLY) j = journal.Reader(journal.SYSTEM_ONLY)
j.seek_tail() j.seek_tail()
j.get_previous() j.get_previous()
@ -25,7 +25,9 @@ def _doForEachJournalEntry(fct):
event = j.wait(None) event = j.wait(None)
if event == journal.APPEND: if event == journal.APPEND:
for entry in j: for entry in j:
fct(entry) step = workflow.firstStep
while step is not None:
step = step.run(entry)
def boot(modName): def boot(modName):
if "action_" in modName: if "action_" in modName:
@ -39,7 +41,7 @@ def main():
_setPyrusePaths() _setPyrusePaths()
conf = config.Config(PYRUSE_PATHS).asMap().get("actions", {}) conf = config.Config(PYRUSE_PATHS).asMap().get("actions", {})
wf = workflow.Workflow(conf) wf = workflow.Workflow(conf)
_doForEachJournalEntry(wf.run) _doForEachJournalEntry(wf)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -18,10 +18,7 @@ class Workflow:
for setter in dangling: for setter in dangling:
setter(entryPoint) setter(entryPoint)
dangling = newDangling dangling = newDangling
self.run = firstStep.run if firstStep else self._noRun self.firstStep = firstStep
def _noRun(self, whatever):
pass
def _initChain(self, actions, label, seen): def _initChain(self, actions, label, seen):
dangling = [] dangling = []

View File

@ -53,9 +53,9 @@ def main():
] ]
_clean() _clean()
for e in test: for e in test:
wf.run(e) run(wf, e)
actions.action_dailyReport.Action._hour = 25 actions.action_dailyReport.Action._hour = 25
wf.run(entry("bck", "login", "Failed password for root from ::1", 11)) run(wf, entry("bck", "login", "Failed password for root from ::1", 11))
for f in ['acted_on.log', 'email.dump', 'nftBan.cmd', 'unfiltered.log']: for f in ['acted_on.log', 'email.dump', 'nftBan.cmd', 'unfiltered.log']:
assert os.path.exists(f), "file should exist: " + f assert os.path.exists(f), "file should exist: " + f
try: try:
@ -83,5 +83,10 @@ def entry(host, service, message, microsecond = None):
"MESSAGE": message "MESSAGE": message
} }
def run(workflow, logEntry):
step = workflow.firstStep
while step is not None:
step = step.run(logEntry)
if __name__ == '__main__': if __name__ == '__main__':
main() main()