Changelog¶
All notable changes to this project will be documented in this file.
[0.6.0] - 2025.12.18¶
Breaking Changes¶
- Removed
notifyparameter from manual control methods: Thenotifyparameter has been removed fromreset(),disable(),metrics_only(), andforce_open()methods. Listeners are now always notified on state transitions.
[0.5.1] - 2025.12.17¶
Fixed¶
- SlackListener thread management: Improved thread lifecycle for manual state transitions.
- Thread now ends on transitions to
CLOSED,DISABLED, orMETRICS_ONLY(previously onlyHALF_OPEN → CLOSED) - Thread continues on transitions to
FORCED_OPENsince the failure cycle persists - Direct
reset()fromOPENnow properly clears the thread for the next failure cycle
- Thread now ends on transitions to
[0.5.0] - 2025.12.16¶
Added¶
Allpermit strategy: A simple permit that always allows all calls inHALF_OPENstate. Useful for testing or when you want to rely solely on the tripper for state transitions.
from fluxgate import CircuitBreaker
from fluxgate.permits import All
cb = CircuitBreaker(name="api", permit=All())
TemplateTypedDict for SlackListener: Customize Slack message templates by subclassingSlackListenerand overridingTRANSITION_TEMPLATESandFALLBACK_TEMPLATEclass attributes.
from fluxgate.listeners.slack import SlackListener, Template
from fluxgate.state import StateEnum
class CustomSlackListener(SlackListener):
TRANSITION_TEMPLATES: dict[tuple[StateEnum, StateEnum], Template] = {
(StateEnum.CLOSED, StateEnum.OPEN): {
"title": "🚨 Alert",
"color": "#FF0000",
"description": "Circuit opened!",
},
}
[0.4.1] - 2025.12.15¶
Added¶
- Sensible defaults for CircuitBreaker: All component parameters now have default values, allowing simpler initialization with just a name:
from fluxgate import CircuitBreaker
cb = CircuitBreaker("my-service")
@cb
def call_api():
return requests.get("https://api.example.com")
Default values:
window:CountWindow(100)tracker:All()tripper:MinRequests(100) & (FailureRate(0.5) | SlowRate(1.0))retry:Cooldown(60.0)permit:RampUp(0.0, 1.0, 60.0)slow_threshold:60.0
[0.4.0] - 2025.12.05¶
Breaking Changes¶
AvgLatencynow uses>=instead of>: The tripper now trips when the average latency reaches or exceeds the threshold, consistent with other rate-based trippers (FailureRate,SlowRate).TypeOfnow requires at least one exception type: CreatingTypeOf()without arguments now raisesValueError.
Fixed¶
SlackListenerno longer crashes on unsupported transitions: Previously, state transitions not in the predefined message templates (e.g.,DISABLED,FORCED_OPEN,METRICS_ONLY, or manualreset()fromOPENtoCLOSED) would raiseKeyError. Now these transitions are silently ignored.
[0.3.1] - 2025.12.05¶
Breaking Changes¶
ITripper.consecutive_failuresis now required: Theconsecutive_failuresparameter no longer has a default value. Custom tripper implementations must pass this argument explicitly.
[0.3.0] - 2025.12.05¶
Breaking Changes¶
ITripperinterface signature changed: The__call__method now accepts aconsecutive_failuresparameter. Custom tripper implementations must update their signature:
# Before (v0.2.x)
def __call__(self, metric: Metric, state: StateEnum) -> bool: ...
# After (v0.3.0)
def __call__(self, metric: Metric, state: StateEnum, consecutive_failures: int = 0) -> bool: ...
Added¶
FailureStreaktripper: Trip the circuit after N consecutive failures. Useful for fast failure detection during cold start or complete service outage.
from fluxgate.trippers import FailureStreak, MinRequests, FailureRate
# Fast trip on 5 consecutive failures, or statistical trip on 50% failure rate
tripper = FailureStreak(5) | (MinRequests(20) & FailureRate(0.5))
[0.2.0] - 2025.12.03¶
Breaking Changes¶
slow_thresholdis now required: Theslow_thresholdparameter no longer has a default value and must be explicitly set when creatingCircuitBreakerorAsyncCircuitBreakerinstances.- If you don't use
SlowRate, set it tofloat("inf")to disable slow call tracking. - This follows Python's principle: "Explicit is better than implicit."
- If you don't use
Migration:
# Before (v0.1.x)
cb = CircuitBreaker(
name="api",
window=CountWindow(size=100),
...
)
# After (v0.2.0)
cb = CircuitBreaker(
name="api",
window=CountWindow(size=100),
...
slow_threshold=float("inf"), # or a specific value like 3.0
)
[0.1.2] - 2025.12.03¶
Changed¶
- LogListener: Added
loggerandlevel_mapparameters for flexible logging configuration.logger: Inject a custom logger instance instead of using the root logger.level_map: Customize log levels per state (default:OPEN/FORCED_OPEN→WARNING, others →INFO).
[0.1.1] - 2025.12.01¶
This is the initial public release of Fluxgate.
Features¶
- ✨ Core: Initial implementation of
CircuitBreakerandAsyncCircuitBreaker. - ✨ Windows: Sliding window strategies (
CountWindow,TimeWindow). - ✨ Trackers: Composable failure trackers (
All,TypeOf,Custom) with&,|, and~operators. - ✨ Trippers: Composable tripping conditions (
Closed,HalfOpened,MinRequests,FailureRate,AvgLatency,SlowRate) with&and|operators. - ✨ Retries: Recovery strategies (
Never,Always,Cooldown,Backoff). - ✨ Permits: Gradual recovery strategies (
Random,RampUp). - ✨ Listeners: Built-in monitoring and alerting integrations (
LogListener,PrometheusListener,SlackListener). - ✨ Manual Control: Methods for manual intervention (
disable,metrics_only,force_open,reset). - ✨ Typing: Full type hinting and
py.typedcompliance for excellent IDE support.