-
Notifications
You must be signed in to change notification settings - Fork 0
demo: idempotency tech-debt — falsy responses + Redis None handling #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -167,7 +167,7 @@ def _process_idempotency(self, is_replay: bool): | |
| # We give preference to ReturnValuesOnConditionCheckFailure because it is a faster and more cost-effective | ||
| # way of retrieving the existing record after a failed conditional write operation. | ||
| record = exc.old_data_record or self._get_idempotency_record() | ||
| if is_replay and record is not None and record.status == STATUS_CONSTANTS["INPROGRESS"]: | ||
| if is_replay and record is not None and record.status == "INPROGRESS": | ||
| return self._get_function_response() | ||
| # If a record is found, handle it for status | ||
| if record: | ||
|
|
@@ -296,7 +296,7 @@ def _get_function_response(self): | |
|
|
||
| else: | ||
| try: | ||
| serialized_response: dict = self.output_serializer.to_dict(response) if response is not None else None | ||
| serialized_response: dict = self.output_serializer.to_dict(response) if response else None | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BUG: Falsy-but-valid responses (
Refutation trail (why this survived the Critic's disprove pass)Hypothesis (Investigator): Changing Disprove attempt (Critic): Read base.py:282-307. The The Critic's default verdict is OVERTURNED. UPHELD findings are those it tried — and failed — to refute. |
||
| self.persistence_store.save_success(data=self.data, result=serialized_response) | ||
| except Exception as save_exception: | ||
| raise IdempotencyPersistenceLayerError( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -335,8 +335,8 @@ def _item_to_data_record(self, idempotency_key: str, item: dict[str, Any]) -> Da | |
| idempotency_key=idempotency_key, | ||
| status=item[self.status_attr], | ||
| in_progress_expiry_timestamp=in_progress_expiry_timestamp, | ||
| response_data=item.get(self.data_attr, ""), | ||
| payload_hash=item.get(self.validation_key_attr, ""), | ||
| response_data=str(item.get(self.data_attr)), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BUG: When a Redis idempotency record is missing
Refutation trail (why this survived the Critic's disprove pass)Hypothesis (Investigator): Wrapping Disprove attempt (Critic): Read redis.py lines 331-341 — The Critic's default verdict is OVERTURNED. UPHELD findings are those it tried — and failed — to refute. |
||
| payload_hash=str(item.get(self.validation_key_attr)), | ||
| expiry_timestamp=item.get("expiration"), | ||
| ) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DESIGN: Hardcoding the literal
"INPROGRESS"here couples the replay-resume branch to an implementation detail of the constants table. All other call sites (base.py:253, 256; persistence/base.py:239, 280, 313; dynamodb.py:246; redis.py:421, 429, 481) uniformly useSTATUS_CONSTANTS["INPROGRESS"]. This inconsistency creates drift risk: if the constants dict is refactored or renamed, this branch alone is not updated.Refutation trail (why this survived the Critic's disprove pass)
Hypothesis (Investigator): Replacing
STATUS_CONSTANTS["INPROGRESS"]with the literal"INPROGRESS"introduces drift risk and inconsistency — if the constant value ever changes, this branch silently breaks; meanwhile every other call site (lines 253, 256, persistence/base.py:239, 280, 313, dynamodb.py:246, redis.py:421, 429, 481) uses the constant.Disprove attempt (Critic): Read datarecord.py:14 —
STATUS_CONSTANTS = MappingProxyType({"INPROGRESS": "INPROGRESS", ...}). Today the literal equals the constant value, so behavior is unchanged. grep_codebase confirmed all sibling sites use the constant indirection.The Critic's default verdict is OVERTURNED. UPHELD findings are those it tried — and failed — to refute.