Browse Source

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

master
Yves G 3 years ago
committed by Y
parent
commit
dea4b5a016
5 changed files with 15 additions and 14 deletions
  1. +0
    -1
      TODO.md
  2. +2
    -4
      pyruse/base.py
  3. +5
    -3
      pyruse/main.py
  4. +1
    -4
      pyruse/workflow.py
  5. +7
    -2
      tests/main.py

+ 0
- 1
TODO.md View File

@ -2,5 +2,4 @@
* 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 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…

+ 2
- 4
pyruse/base.py View File

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

+ 5
- 3
pyruse/main.py View File

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

+ 1
- 4
pyruse/workflow.py View File

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


+ 7
- 2
tests/main.py View File

@ -53,9 +53,9 @@ def main():
]
_clean()
for e in test:
wf.run(e)
run(wf, e)
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']:
assert os.path.exists(f), "file should exist: " + f
try:
@ -83,5 +83,10 @@ def entry(host, service, message, microsecond = None):
"MESSAGE": message
}
def run(workflow, logEntry):
step = workflow.firstStep
while step is not None:
step = step.run(logEntry)
if __name__ == '__main__':
main()

Loading…
Cancel
Save