Skip to content

Commit 3fe4955

Browse files
committed
fix(action_log): Refine usage of idempotency key
1 parent 2381228 commit 3fe4955

4 files changed

Lines changed: 4 additions & 52 deletions

File tree

src/sentry/issues/action_log/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from sentry.issues.action_log.base import (
22
ActionContext,
33
ActionSource,
4-
DuplicateActionError,
54
action_context_scope,
65
get_action_context,
76
publish_action,
@@ -13,7 +12,6 @@
1312
__all__ = [
1413
"ActionContext",
1514
"ActionSource",
16-
"DuplicateActionError",
1715
"GroupActionActor",
1816
"SYSTEM_ACTOR",
1917
"action_context_scope",

src/sentry/issues/action_log/base.py

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from dataclasses import dataclass
88
from enum import StrEnum
99

10-
from django.db import IntegrityError, router, transaction
1110
from rest_framework.request import Request
1211

1312
from sentry import options
@@ -134,10 +133,6 @@ def get_action_context() -> ActionContext | None:
134133
return _action_context.get()
135134

136135

137-
class DuplicateActionError(Exception):
138-
"""Raised when an idempotency_key conflicts with an existing entry."""
139-
140-
141136
def publish_action(
142137
action: GroupAction,
143138
*,
@@ -146,11 +141,9 @@ def publish_action(
146141
organization_id: int,
147142
project_id: int,
148143
actor: GroupActionActor = SYSTEM_ACTOR,
149-
idempotency_key: str | None = None,
150144
) -> None:
151145
"""
152-
Record an issue action. Raises DuplicateActionError if an idempotency_key
153-
conflicts with an existing entry.
146+
Record an issue action.
154147
155148
Use this for shallow endpoint-level actions where the request is in scope
156149
(VIEW, COMMENT, TRIGGER_AUTOFIX). For mutation sites deeper in the stack,
@@ -171,42 +164,23 @@ def publish_action(
171164
"actor_type": actor.actor_type.name.lower(),
172165
"actor_id": str(actor.actor_id),
173166
"metadata": action.dict(),
174-
"idempotency_key": idempotency_key,
175167
},
176168
)
177169

178170
# Don't write to the database until we're confident in the action schemas.
179171
if not options.get("issues.action-log.write-to-db"):
180172
return
181173

182-
kwargs = dict(
174+
GroupActionLogEntry.objects.create(
183175
group_id=group_id,
184176
project_id=project_id,
185177
type=action.get_type().value,
186178
actor_type=actor.actor_type.value,
187179
actor_id=actor.actor_id,
188180
source=source,
189181
data=action.dict(),
190-
idempotency_key=idempotency_key,
191182
)
192183

193-
if idempotency_key is None:
194-
GroupActionLogEntry.objects.create(**kwargs)
195-
return
196-
197-
try:
198-
with transaction.atomic(using=router.db_for_write(GroupActionLogEntry)):
199-
GroupActionLogEntry.objects.create(**kwargs)
200-
except IntegrityError as e:
201-
cause = e.__cause__
202-
constraint = getattr(getattr(cause, "diag", None), "constraint_name", None)
203-
if constraint == "uniq_groupactionlogentry_group_idempotency_key":
204-
raise DuplicateActionError(
205-
f"Action already recorded for group {group_id} "
206-
f"with idempotency_key={idempotency_key!r}"
207-
) from e
208-
raise
209-
210184

211185
def publish_action_from_context(
212186
action: GroupAction,

src/sentry/issues/groupactionlogentry.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ class GroupActionLogEntry(Model):
5959
# for invalidation.
6060
date_updated = models.DateTimeField(auto_now=True)
6161

62-
# Partial unique index with group_id prevents duplicate events.
62+
# Unique identifier for external action this corresponds to.
63+
# Primarly exists to make backfilling third party actions simpler.
6364
idempotency_key = models.CharField(max_length=64, null=True)
6465

6566
class Meta:

tests/sentry/issues/test_action_log.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
from typing import Any
22
from unittest.mock import MagicMock, patch
33

4-
import pytest
5-
64
import sentry.api.helpers.group_index.update
75
import sentry.issues.endpoints.group_details
86
import sentry.issues.endpoints.group_integration_details
@@ -14,7 +12,6 @@
1412
from sentry.issues.action_log import (
1513
SYSTEM_ACTOR,
1614
ActionContext,
17-
DuplicateActionError,
1815
GroupActionActor,
1916
action_context_scope,
2017
get_action_context,
@@ -576,24 +573,6 @@ def test_multiple_entries_ordered(self) -> None:
576573
assert len(entries) == 3
577574
assert entries[0].id < entries[1].id < entries[2].id
578575

579-
def test_duplicate_idempotency_key_raises(self) -> None:
580-
kwargs = dict(
581-
source=ActionSource.API,
582-
group_id=self.group.id,
583-
organization_id=self.group.project.organization_id,
584-
project_id=self.group.project_id,
585-
actor=GroupActionActor.user(self.user.id),
586-
idempotency_key="view-123",
587-
)
588-
589-
with self.options({"issues.action-log.write-to-db": True}):
590-
publish_action(ViewAction(), **kwargs)
591-
592-
with pytest.raises(DuplicateActionError):
593-
publish_action(ViewAction(), **kwargs)
594-
595-
assert GroupActionLogEntry.objects.filter(group_id=self.group.id).count() == 1
596-
597576
def test_option_disabled_skips_write(self) -> None:
598577
with self.options({"issues.action-log.write-to-db": False}):
599578
publish_action(

0 commit comments

Comments
 (0)