"""单进程预算与重复失败演示；不是分布式限流器。"""
from collections import Counter
from contracts import digest

class Budget:
    def __init__(self, max_calls=5):
        self.remaining = max_calls
        self.failures = Counter()

    def before_call(self):
        if self.remaining <= 0:
            raise ValueError("budget_exhausted")
        self.remaining -= 1

    def failed(self, tool, arguments, error):
        # 参数变化产生不同指纹；语义相同但文本不同的情况仍依赖总预算兜底。
        fingerprint = digest([tool, arguments, error])
        self.failures[fingerprint] += 1
        return self.failures[fingerprint] >= 3

if __name__ == "__main__":
    budget = Budget()
    for _ in range(3):
        budget.before_call()
        stop = budget.failed("read", {"resource": "missing"}, "not_found")
        print({"stop_repeating": stop, "remaining": budget.remaining})
