Hello, I wanted to share something I've recently discovered - there is a strange issue with cinder evaluating complex configuration formulas. For example when using complex goodness_function it's quite easy to hit: ERROR cinder.scheduler.weights.goodness maximum recursion depth exceeded: RecursionError: maximum recursion depth exceeded I did some tests to find the root cause. It seems that pyparsing module does deep recursive parsing quite a lot (default recursion limit is 1000). Not sure how to solve it but it would be nice to at least have a warning in the docs. Results and methodology below. Tests were done using following code snippet ------------------------------------------- from cinder.scheduler.evaluator.evaluator import evaluate import sys formulas = [ "1", "1 + 1", "max(1, 2, 3)", "max(1 + (10 / 20), 2, 3)", "(1 + max(1 + (10 / 20), 2, 3)) / 100", "((1 + max(1 + (10 / 20), 2, 3)) / 100) + stats.total_capacity_gb", "(((1 + max(1 + (10 / 20), 2, 3)) / 100) + stats.total_capacity_gb) / 100", ] stats = { 'allocated_capacity_gb': 50000, 'total_capacity_gb': 60000, 'free_capacity_gb': 10000, } for f in formulas: for i in range(10, 2000, 10): sys.setrecursionlimit(i) try: res = evaluate(f, stats=stats) print(f"{i}: {f}") break except RecursionError: pass Test results -------------------------------- Cinder 14.3.1, pyparsing<3.0 210: 1 210: 1 + 1 450: max(1, 2, 3) 600: max(1 + (10 / 20), 2, 3) 790: (1 + max(1 + (10 / 20), 2, 3)) / 100 980: ((1 + max(1 + (10 / 20), 2, 3)) / 100) + stats.total_capacity_gb 1160: (((1 + max(1 + (10 / 20), 2, 3)) / 100) + stats.total_capacity_gb) / 100 Cinder 16.4.2, pyparsing<3.0 220: 1 220: 1 + 1 450: max(1, 2, 3) 610: max(1 + (10 / 20), 2, 3) 790: (1 + max(1 + (10 / 20), 2, 3)) / 100 980: ((1 + max(1 + (10 / 20), 2, 3)) / 100) + stats.total_capacity_gb 1170: (((1 + max(1 + (10 / 20), 2, 3)) / 100) + stats.total_capacity_gb) / 100 Cinder 19.1.0, pyparsing<3.0 220: 1 220: 1 + 1 450: max(1, 2, 3) 610: max(1 + (10 / 20), 2, 3) 790: (1 + max(1 + (10 / 20), 2, 3)) / 100 980: ((1 + max(1 + (10 / 20), 2, 3)) / 100) + stats.total_capacity_gb 1170: (((1 + max(1 + (10 / 20), 2, 3)) / 100) + stats.total_capacity_gb) / 100 BR