Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions aws_lambda_powertools/utilities/circuit_breaker/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Circuit Breaker utility for protecting unhealthy downstream dependencies.
"""

from aws_lambda_powertools.utilities.circuit_breaker.circuit_breaker import circuit_breaker
from aws_lambda_powertools.utilities.circuit_breaker.config import CircuitBreakerConfig
from aws_lambda_powertools.utilities.circuit_breaker.exceptions import (
CircuitBreakerConfigError,
CircuitBreakerError,
CircuitBreakerOpenError,
CircuitBreakerPersistenceError,
)
from aws_lambda_powertools.utilities.circuit_breaker.states import (
CircuitInfo,
CircuitState,
CircuitTransition,
)

__all__ = (
"circuit_breaker",
"CircuitBreakerConfig",
"CircuitInfo",
"CircuitState",
"CircuitTransition",
"CircuitBreakerError",
"CircuitBreakerOpenError",
"CircuitBreakerConfigError",
"CircuitBreakerPersistenceError",
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
import uuid
from typing import TYPE_CHECKING, Any

from aws_lambda_powertools.utilities.circuit_breaker_alpha.exceptions import CircuitBreakerOpenError
from aws_lambda_powertools.utilities.circuit_breaker_alpha.states import CircuitState, CircuitTransition
from aws_lambda_powertools.utilities.circuit_breaker.exceptions import CircuitBreakerOpenError
from aws_lambda_powertools.utilities.circuit_breaker.states import CircuitState, CircuitTransition

if TYPE_CHECKING:
from collections.abc import Callable

from aws_lambda_powertools.utilities.circuit_breaker_alpha.config import CircuitBreakerConfig
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence.base import (
from aws_lambda_powertools.utilities.circuit_breaker.config import CircuitBreakerConfig
from aws_lambda_powertools.utilities.circuit_breaker.persistence.base import (
CircuitBreakerPersistenceLayer,
)
from aws_lambda_powertools.utilities.circuit_breaker_alpha.states import CircuitInfo
from aws_lambda_powertools.utilities.circuit_breaker.states import CircuitInfo

logger = logging.getLogger(__name__)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@

from aws_lambda_powertools.shared import constants
from aws_lambda_powertools.shared.functions import strtobool
from aws_lambda_powertools.utilities.circuit_breaker_alpha.base import CircuitBreakerHandler
from aws_lambda_powertools.utilities.circuit_breaker_alpha.config import CircuitBreakerConfig
from aws_lambda_powertools.utilities.circuit_breaker.base import CircuitBreakerHandler
from aws_lambda_powertools.utilities.circuit_breaker.config import CircuitBreakerConfig
from aws_lambda_powertools.warnings import PowertoolsUserWarning

if TYPE_CHECKING:
from collections.abc import Callable

from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence.base import (
from aws_lambda_powertools.utilities.circuit_breaker.persistence.base import (
CircuitBreakerPersistenceLayer,
)

Expand Down Expand Up @@ -73,8 +73,8 @@ def circuit_breaker(
-------
**Protect a payment backend, buffering rejected requests**

from aws_lambda_powertools.utilities.circuit_breaker_alpha import circuit_breaker, CircuitInfo
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence import (
from aws_lambda_powertools.utilities.circuit_breaker import circuit_breaker, CircuitInfo
from aws_lambda_powertools.utilities.circuit_breaker.persistence import (
CircuitBreakerDynamoDBPersistence,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from typing import TYPE_CHECKING

from aws_lambda_powertools.utilities.circuit_breaker_alpha.exceptions import CircuitBreakerConfigError
from aws_lambda_powertools.utilities.circuit_breaker.exceptions import CircuitBreakerConfigError

if TYPE_CHECKING:
from collections.abc import Iterable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from aws_lambda_powertools.utilities.circuit_breaker_alpha.states import CircuitInfo
from aws_lambda_powertools.utilities.circuit_breaker.states import CircuitInfo


class CircuitBreakerError(Exception):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Persistence layers for the Circuit Breaker utility.
"""

from aws_lambda_powertools.utilities.circuit_breaker.persistence.base import CircuitBreakerPersistenceLayer
from aws_lambda_powertools.utilities.circuit_breaker.persistence.dynamodb import (
CircuitBreakerDynamoDBPersistence,
)
from aws_lambda_powertools.utilities.circuit_breaker.persistence.record import CircuitStateRecord

__all__ = (
"CircuitBreakerPersistenceLayer",
"CircuitBreakerDynamoDBPersistence",
"CircuitStateRecord",
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
from typing import TYPE_CHECKING, NamedTuple

from aws_lambda_powertools.shared.cache_dict import LRUDict
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence.record import CircuitStateRecord
from aws_lambda_powertools.utilities.circuit_breaker_alpha.states import CircuitState
from aws_lambda_powertools.utilities.circuit_breaker.persistence.record import CircuitStateRecord
from aws_lambda_powertools.utilities.circuit_breaker.states import CircuitState

if TYPE_CHECKING:
from aws_lambda_powertools.utilities.circuit_breaker_alpha.config import CircuitBreakerConfig
from aws_lambda_powertools.utilities.circuit_breaker.config import CircuitBreakerConfig

logger = logging.getLogger(__name__)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
from botocore.exceptions import ClientError

from aws_lambda_powertools.shared import constants, user_agent
from aws_lambda_powertools.utilities.circuit_breaker_alpha.exceptions import CircuitBreakerConfigError
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence.base import (
from aws_lambda_powertools.utilities.circuit_breaker.exceptions import CircuitBreakerConfigError
from aws_lambda_powertools.utilities.circuit_breaker.persistence.base import (
CircuitBreakerExistingLockError,
CircuitBreakerPersistenceLayer,
)
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence.record import CircuitStateRecord
from aws_lambda_powertools.utilities.circuit_breaker_alpha.states import CircuitState
from aws_lambda_powertools.utilities.circuit_breaker.persistence.record import CircuitStateRecord
from aws_lambda_powertools.utilities.circuit_breaker.states import CircuitState
from aws_lambda_powertools.warnings import PowertoolsUserWarning

if TYPE_CHECKING:
Expand Down Expand Up @@ -75,7 +75,7 @@ class CircuitBreakerDynamoDBPersistence(CircuitBreakerPersistenceLayer):
-------
**Create a DynamoDB-backed circuit breaker store**

from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence import (
from aws_lambda_powertools.utilities.circuit_breaker.persistence import (
CircuitBreakerDynamoDBPersistence,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from dataclasses import dataclass

from aws_lambda_powertools.utilities.circuit_breaker_alpha.states import CircuitInfo, CircuitState
from aws_lambda_powertools.utilities.circuit_breaker.states import CircuitInfo, CircuitState


@dataclass
Expand Down

This file was deleted.

This file was deleted.

2 changes: 2 additions & 0 deletions docs/api_doc/circuit_breaker/circuit_breaker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!-- markdownlint-disable MD043 MD041 -->
::: aws_lambda_powertools.utilities.circuit_breaker.circuit_breaker
2 changes: 2 additions & 0 deletions docs/api_doc/circuit_breaker/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!-- markdownlint-disable MD043 MD041 -->
::: aws_lambda_powertools.utilities.circuit_breaker.config
2 changes: 2 additions & 0 deletions docs/api_doc/circuit_breaker/exceptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!-- markdownlint-disable MD043 MD041 -->
::: aws_lambda_powertools.utilities.circuit_breaker.exceptions
2 changes: 2 additions & 0 deletions docs/api_doc/circuit_breaker/persistence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!-- markdownlint-disable MD043 MD041 -->
::: aws_lambda_powertools.utilities.circuit_breaker.persistence
2 changes: 2 additions & 0 deletions docs/api_doc/circuit_breaker/states.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!-- markdownlint-disable MD043 MD041 -->
::: aws_lambda_powertools.utilities.circuit_breaker.states
2 changes: 0 additions & 2 deletions docs/api_doc/circuit_breaker_alpha/circuit_breaker.md

This file was deleted.

2 changes: 0 additions & 2 deletions docs/api_doc/circuit_breaker_alpha/config.md

This file was deleted.

2 changes: 0 additions & 2 deletions docs/api_doc/circuit_breaker_alpha/exceptions.md

This file was deleted.

2 changes: 0 additions & 2 deletions docs/api_doc/circuit_breaker_alpha/persistence.md

This file was deleted.

2 changes: 0 additions & 2 deletions docs/api_doc/circuit_breaker_alpha/states.md

This file was deleted.

21 changes: 7 additions & 14 deletions docs/utilities/circuit_breaker.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@ description: Utility

<!-- markdownlint-disable MD051 -->

!!! warning "Alpha / experimental"
This utility ships under the **`circuit_breaker_alpha`** namespace while we collect
feedback. The public API may change in a backwards-incompatible way before it is
promoted to GA, at which point the import path becomes `circuit_breaker`. Pin your
Powertools version and follow the tracking discussion before relying on it in
production.

The circuit breaker utility stops sending traffic to an unhealthy downstream dependency, giving it room to recover while you decide what happens to the rejected requests.

## Key features
Expand Down Expand Up @@ -99,7 +92,7 @@ You **can** use a single DynamoDB table for all your circuits. Already have a si
=== "AWS Serverless Application Model (SAM) example"

```yaml hl_lines="3-15 24-29 32-33"
--8<-- "examples/circuit_breaker_alpha/templates/sam.yaml"
--8<-- "examples/circuit_breaker/templates/sam.yaml"
```

### Circuit breaker in action
Expand All @@ -109,7 +102,7 @@ The common case is the `@circuit_breaker` decorator wrapping the function that m
=== "getting_started_with_circuit_breaker.py"

```python hl_lines="3-6 9 19 27"
--8<-- "examples/circuit_breaker_alpha/src/getting_started_with_circuit_breaker.py"
--8<-- "examples/circuit_breaker/src/getting_started_with_circuit_breaker.py"
```

!!! note "Wrap the downstream call, not the whole handler"
Expand Down Expand Up @@ -137,7 +130,7 @@ Register an `on_circuit_open` callback to decide what happens to a rejected requ
=== "working_with_callback.py"

```python hl_lines="6 24-28 31-35"
--8<-- "examples/circuit_breaker_alpha/src/working_with_callback.py"
--8<-- "examples/circuit_breaker/src/working_with_callback.py"
```

!!! info "Why a callback instead of built-in S3/SQS sinks?"
Expand All @@ -152,7 +145,7 @@ If you don't register a callback, an open circuit raises `CircuitBreakerOpenErro
=== "working_without_callback.py"

```python hl_lines="5 16-22 38-43"
--8<-- "examples/circuit_breaker_alpha/src/working_without_callback.py"
--8<-- "examples/circuit_breaker/src/working_without_callback.py"
```

## Configuration
Expand Down Expand Up @@ -211,7 +204,7 @@ Register an `on_transition` hook to be notified whenever the circuit changes sta
=== "working_with_metrics.py"

```python hl_lines="3 12-21 26"
--8<-- "examples/circuit_breaker_alpha/src/working_with_metrics.py"
--8<-- "examples/circuit_breaker/src/working_with_metrics.py"
```

Any exception raised inside the hook is swallowed and logged, so a misbehaving metric call can never break the protected request.
Expand All @@ -234,14 +227,14 @@ Set **`POWERTOOLS_CIRCUIT_BREAKER_DISABLED`**{: .copyMe} to a truthy value to by

#### Using a composite primary key

Use the `sort_key_attr` parameter when your table is configured with a composite primary key _(hash+range key)_, as in a single-table design.
Use the `sort_key_attr` parameter when your table is configured with a composite primary key *(hash+range key)*, as in a single-table design.

When enabled, the circuit name is saved in the sort key instead, and the partition key defaults to `circuit_breaker#{LAMBDA_FUNCTION_NAME}` — this **namespaces circuits per function** so two functions can use the same circuit name without sharing state. (Without `sort_key_attr`, the default remains partition-key-only with the circuit name as the partition key.)

Set `static_pk_value` to a fixed value (as below) when you instead want **multiple functions to share the same circuit** — for example, every function guarding the same downstream dependency should trip together.

```python hl_lines="12-14"
--8<-- "examples/circuit_breaker_alpha/src/working_with_composite_primary_key.py"
--8<-- "examples/circuit_breaker/src/working_with_composite_primary_key.py"
```

??? note "Click to expand and learn how table items would look like"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os

from aws_lambda_powertools.utilities.circuit_breaker_alpha import circuit_breaker
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence import (
from aws_lambda_powertools.utilities.circuit_breaker import circuit_breaker
from aws_lambda_powertools.utilities.circuit_breaker.persistence import (
CircuitBreakerDynamoDBPersistence,
)
from aws_lambda_powertools.utilities.typing import LambdaContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import boto3

from aws_lambda_powertools.utilities.circuit_breaker_alpha import CircuitInfo, circuit_breaker
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence import (
from aws_lambda_powertools.utilities.circuit_breaker import CircuitInfo, circuit_breaker
from aws_lambda_powertools.utilities.circuit_breaker.persistence import (
CircuitBreakerDynamoDBPersistence,
)
from aws_lambda_powertools.utilities.typing import LambdaContext
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os

from aws_lambda_powertools.utilities.circuit_breaker_alpha import circuit_breaker
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence import (
from aws_lambda_powertools.utilities.circuit_breaker import circuit_breaker
from aws_lambda_powertools.utilities.circuit_breaker.persistence import (
CircuitBreakerDynamoDBPersistence,
)
from aws_lambda_powertools.utilities.typing import LambdaContext
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import os

from aws_lambda_powertools.metrics import MetricUnit, single_metric
from aws_lambda_powertools.utilities.circuit_breaker_alpha import (
from aws_lambda_powertools.utilities.circuit_breaker import (
CircuitTransition,
circuit_breaker,
)
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence import (
from aws_lambda_powertools.utilities.circuit_breaker.persistence import (
CircuitBreakerDynamoDBPersistence,
)
from aws_lambda_powertools.utilities.typing import LambdaContext
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import os

from aws_lambda_powertools.utilities.circuit_breaker_alpha import (
from aws_lambda_powertools.utilities.circuit_breaker import (
CircuitBreakerConfig,
CircuitBreakerOpenError,
circuit_breaker,
)
from aws_lambda_powertools.utilities.circuit_breaker_alpha.persistence import (
from aws_lambda_powertools.utilities.circuit_breaker.persistence import (
CircuitBreakerDynamoDBPersistence,
)
from aws_lambda_powertools.utilities.typing import LambdaContext
Expand Down
Loading