feat(circuit_breaker): support composite primary key in DynamoDB persistence#8316
Conversation
…istence Add optional `sort_key_attr` and `static_pk_value` parameters to CircuitBreakerDynamoDBPersistence so circuit state can be stored in a single-table (composite key) design, mirroring the Idempotency utility. When `sort_key_attr` is set, the circuit name is written to the sort key and `static_pk_value` to the partition key (default `circuit_breaker#<function-name>`); omit it for the current partition-key-only behavior. The composite key is threaded through the get, conditional put (half-open probe election) and update paths. Includes Stubber-based tests for both modes, docs, and an example. Closes aws-powertools#8315
leandrodamascena
left a comment
There was a problem hiding this comment.
Really nice work. One small thing: static_pk_value only does anything when sort_key_attr is set. If someone passes it alone it's silently ignored, which is annoying to debug. Could we warn?
if static_pk_value is not None and sort_key_attr is None:
warnings.warn(
"static_pk_value is ignored unless sort_key_attr is also set.",
category=PowertoolsUserWarning,
stacklevel=2,
)|
Checking errors. Duplicated file name for the example. Fixing. |
…sename so mypy no longer clashes with the idempotency example.
Yes, it came up in my own reviews and I skipped doing in. Serves me right. Will also add a test like there already is for the other guards. Doing now. |
…rt_key_attr since it is otherwise silently ignored.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #8316 +/- ##
========================================
Coverage 96.63% 96.63%
========================================
Files 296 296
Lines 14689 14704 +15
Branches 1231 1235 +4
========================================
+ Hits 14194 14209 +15
Misses 360 360
Partials 135 135 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
leandrodamascena
left a comment
There was a problem hiding this comment.
Thanks a lot for addressing it @Iamrodos! APPROVED!



Issue number: closes #8315
Summary
Changes
CircuitBreakerDynamoDBPersistencelets you rename attributes but assumes a partition-key-only table. Against a single-table design that uses a composite (partition + sort) key, DynamoDB requires the sort key on every call, so the layer can't operate: it fails open on every invocation (logged at WARNING) and the breaker never trips.This adds optional
sort_key_attrandstatic_pk_valueparameters, matching the composite-key support the Idempotency utility already offers, so there's nothing new to learn for anyone using both. Setsort_key_attrand the circuit name is written to the sort key, withstatic_pk_valuein the partition key (defaultcircuit_breaker#{LAMBDA_FUNCTION_NAME}, which namespaces circuits per function; set it to a fixed value to share one circuit across functions). Omitsort_key_attrand behavior is unchanged — the circuit name stays the partition key, exactly as today.The composite key is threaded through every DynamoDB path the utility uses, not just the read: the
get_itemread, the conditionalput_itemthat elects the single half-open probe, and theupdate_itemon state transitions. So the breaker works end to end on a composite table.Also included: docs (
docs/utilities/circuit_breaker.md) with a "Using a composite primary key" section, a sample-item table, and share-vs-namespace guidance; and a new example,examples/circuit_breaker_alpha/src/working_with_composite_key.py.User experience
Before, a composite-key table couldn't be reused — every call failed and the circuit never tripped:
Now you opt into the existing single-table layout:
Omitting
sort_key_attrkeeps today's partition-key-only behavior, so this is fully backward compatible.Validation
New Stubber-based functional tests cover
get_item/put_item/ conditionalput_item/update_itemin both single-key and composite modes, and assert the read-back name comes from the sort key in composite mode. They also cover thesort_key_attr == key_attrguard and the namespaced default value.By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.