We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add subscription for team in `models/groupsubscription`
Two updates we need to make here:
1) Update `subscribe_actor` (https://github.com/getsentry/sentry/blob/master/src/sentry/models/groupsubscription.py#L67)  to no longer read all the team's users and just set subscribe the Team
2) Update `bulk_subscribe` to allow for bulk subscribing teams, instead of just users

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/sentry/models/groupsubscription.py`
Content:
```
1 from __future__ import annotations
2 
3 from typing import TYPE_CHECKING, Iterable, Optional, Sequence, Union
4 
5 from django.conf import settings
6 from django.db import IntegrityError, models, router, transaction
7 from django.utils import timezone
8 
9 from sentry.backup.scopes import RelocationScope
10 from sentry.db.models import (
11     BaseManager,
12     BoundedPositiveIntegerField,
13     FlexibleForeignKey,
14     Model,
15     region_silo_only_model,
16     sane_repr,
17 )
18 from sentry.db.models.fields.hybrid_cloud_foreign_key import HybridCloudForeignKey
19 from sentry.notifications.helpers import (
20     transform_to_notification_settings_by_recipient,
21     where_should_be_participating,
22 )
23 from sentry.notifications.types import GroupSubscriptionReason, NotificationSettingTypes
24 from sentry.services.hybrid_cloud.actor import RpcActor
25 from sentry.services.hybrid_cloud.notifications import notifications_service
26 from sentry.services.hybrid_cloud.user import RpcUser
27 
28 if TYPE_CHECKING:
29     from sentry.models import Group, Team, User
30     from sentry.notifications.utils.participants import ParticipantMap
31 
32 
33 class GroupSubscriptionManager(BaseManager):
34     def subscribe(
35         self,
36         group: Group,
37         subscriber: User | RpcUser | Team,
38         reason: int = GroupSubscriptionReason.unknown,
39     ) -> bool:
40         """
41         Subscribe a user or team to an issue, but only if that user or team has not explicitly
42         unsubscribed.
43         """
44         from sentry.models import Team, User
45 
46         try:
47             with transaction.atomic(router.db_for_write(GroupSubscription)):
48                 if isinstance(subscriber, (User, RpcUser)):
49                     self.create(
50                         user_id=subscriber.id,
51                         group=group,
52                         project=group.project,
53                         is_active=True,
54                         reason=reason,
55                     )
56                 elif isinstance(subscriber, Team):
57                     self.create(
58                         team=subscriber,
59                         group=group,
60                         project=group.project,
61                         is_active=True,
62                         reason=reason,
63                     )
64         except IntegrityError:
65             pass
66         return True
67 
68     def subscribe_actor(
69         self,
70         group: Group,
71         actor: Union[Team, User, RpcUser],
72         reason: int = GroupSubscriptionReason.unknown,
73     ) -> Optional[bool]:
74         from sentry import features
75         from sentry.models import Team, User
76 
77         if isinstance(actor, (RpcUser, User)):
78             return self.subscribe(group, actor, reason)
79         if isinstance(actor, Team):
80             if features.has("organizations:team-workflow-notifications", group.organization):
81                 return self.subscribe(group, actor, reason)
82             else:
83                 # subscribe the members of the team
84                 team_users_ids = list(actor.member_set.values_list("user_id", flat=True))
85                 return self.bulk_subscribe(group, team_users_ids, reason)
86 
87         raise NotImplementedError("Unknown actor type: %r" % type(actor))
88 
89     def bulk_subscribe(
90         self,
91         group: Group,
92         user_ids: Iterable[int],
93         reason: int = GroupSubscriptionReason.unknown,
94     ) -> bool:
95         """
96         Subscribe a list of user ids to an issue, but only if the users are not explicitly
97         unsubscribed.
98         """
99         # Unique the IDs.
100         user_ids = set(user_ids)
101 
102         # 5 retries for race conditions where
103         # concurrent subscription attempts cause integrity errors
104         for i in range(4, -1, -1):  # 4 3 2 1 0
105 
106             existing_subscriptions = set(
107                 GroupSubscription.objects.filter(
108                     user_id__in=user_ids, group=group, project=group.project
109                 ).values_list("user_id", flat=True)
110             )
111 
112             subscriptions = [
113                 GroupSubscription(
114                     user_id=user_id,
115                     group=group,
116                     project=group.project,
117                     is_active=True,
118                     reason=reason,
119                 )
120                 for user_id in user_ids
121                 if user_id not in existing_subscriptions
122             ]
123 
124             try:
125                 with transaction.atomic(router.db_for_write(GroupSubscription)):
126                     self.bulk_create(subscriptions)
127                     return True
128             except IntegrityError as e:
129                 if i == 0:
130                     raise e
131         return False
132 
133     def get_participants(self, group: Group) -> ParticipantMap:
134         """
135         Identify all users who are participating with a given issue.
136         :param group: Group object
137         """
138         from sentry.notifications.utils.participants import ParticipantMap
139 
140         all_possible_users = RpcActor.many_from_object(group.project.get_members_as_rpc_users())
141         active_and_disabled_subscriptions = self.filter(
142             group=group, user_id__in=[u.id for u in all_possible_users]
143         )
144 
145         notification_settings = notifications_service.get_settings_for_recipient_by_parent(
146             type=NotificationSettingTypes.WORKFLOW,
147             recipients=all_possible_users,
148             parent_id=group.project_id,
149         )
150         subscriptions_by_user_id = {
151             subscription.user_id: subscription for subscription in active_and_disabled_subscriptions
152         }
153         notification_settings_by_recipient = transform_to_notification_settings_by_recipient(
154             notification_settings, all_possible_users
155         )
156 
157         result = ParticipantMap()
158         for user in all_possible_users:
159             subscription_option = subscriptions_by_user_id.get(user.id)
160             providers = where_should_be_participating(
161                 user,
162                 subscription_option,
163                 notification_settings_by_recipient,
164             )
165             for provider in providers:
166                 reason = (
167                     subscription_option
168                     and subscription_option.reason
169                     or GroupSubscriptionReason.implicit
170                 )
171                 result.add(provider, user, reason)
172 
173         return result
174 
175     @staticmethod
176     def get_participating_user_ids(group: Group) -> Sequence[int]:
177         """Return the list of user ids participating in this issue."""
178 
179         return list(
180             GroupSubscription.objects.filter(group=group, is_active=True).values_list(
181                 "user_id", flat=True
182             )
183         )
184 
185 
186 @region_silo_only_model
187 class GroupSubscription(Model):
188     """
189     Identifies a subscription relationship between a user and an issue.
190     """
191 
192     __relocation_scope__ = RelocationScope.Excluded
193 
194     project = FlexibleForeignKey("sentry.Project", related_name="subscription_set")
195     group = FlexibleForeignKey("sentry.Group", related_name="subscription_set")
196     user_id = HybridCloudForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete="CASCADE")
197     team = FlexibleForeignKey("sentry.Team", null=True, db_index=True, on_delete=models.CASCADE)
198     is_active = models.BooleanField(default=True)
199     reason = BoundedPositiveIntegerField(default=GroupSubscriptionReason.unknown)
200     date_added = models.DateTimeField(default=timezone.now, null=True)
201 
202     objects = GroupSubscriptionManager()
203 
204     class Meta:
205         app_label = "sentry"
206         db_table = "sentry_groupsubscription"
207         unique_together = (("group", "user_id"), ("group", "team"))
208         constraints = [
209             models.CheckConstraint(
210                 check=models.Q(team_id__isnull=False, user_id__isnull=True)
211                 | models.Q(team_id__isnull=True, user_id__isnull=False),
212                 name="subscription_team_or_user_check",
213             )
214         ]
215 
216     __repr__ = sane_repr("project_id", "group_id", "user_id")
217
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/sentry/models/groupsubscription.py b/src/sentry/models/groupsubscription.py
--- a/src/sentry/models/groupsubscription.py
+++ b/src/sentry/models/groupsubscription.py
@@ -82,22 +82,28 @@
             else:
                 # subscribe the members of the team
                 team_users_ids = list(actor.member_set.values_list("user_id", flat=True))
-                return self.bulk_subscribe(group, team_users_ids, reason)
+                return self.bulk_subscribe(group=group, user_ids=team_users_ids, reason=reason)
 
         raise NotImplementedError("Unknown actor type: %r" % type(actor))
 
     def bulk_subscribe(
         self,
         group: Group,
-        user_ids: Iterable[int],
+        user_ids: Iterable[int] | None = None,
+        team_ids: Iterable[int] | None = None,
         reason: int = GroupSubscriptionReason.unknown,
     ) -> bool:
         """
-        Subscribe a list of user ids to an issue, but only if the users are not explicitly
+        Subscribe a list of user ids and/or teams to an issue, but only if the users/teams are not explicitly
         unsubscribed.
         """
+        from sentry import features
+
         # Unique the IDs.
-        user_ids = set(user_ids)
+        user_ids = set(user_ids) if user_ids else set()
+
+        # Unique the teams.
+        team_ids = set(team_ids) if team_ids else set()
 
         # 5 retries for race conditions where
         # concurrent subscription attempts cause integrity errors
@@ -117,10 +123,29 @@
                     is_active=True,
                     reason=reason,
                 )
-                for user_id in user_ids
-                if user_id not in existing_subscriptions
+                for user_id in user_ids.difference(existing_subscriptions)
             ]
 
+            if features.has("organizations:team-workflow-notifications", group.organization):
+                existing_team_subscriptions = set(
+                    GroupSubscription.objects.filter(
+                        team_id__in=team_ids, group=group, project=group.project
+                    ).values_list("team_id", flat=True)
+                )
+
+                subscriptions.extend(
+                    [
+                        GroupSubscription(
+                            team_id=team_id,
+                            group=group,
+                            project=group.project,
+                            is_active=True,
+                            reason=reason,
+                        )
+                        for team_id in team_ids.difference(existing_team_subscriptions)
+                    ]
+                )
+
             try:
                 with transaction.atomic(router.db_for_write(GroupSubscription)):
                     self.bulk_create(subscriptions)

{"golden_diff": "diff --git a/src/sentry/models/groupsubscription.py b/src/sentry/models/groupsubscription.py\n--- a/src/sentry/models/groupsubscription.py\n+++ b/src/sentry/models/groupsubscription.py\n@@ -82,22 +82,28 @@\n             else:\n                 # subscribe the members of the team\n                 team_users_ids = list(actor.member_set.values_list(\"user_id\", flat=True))\n-                return self.bulk_subscribe(group, team_users_ids, reason)\n+                return self.bulk_subscribe(group=group, user_ids=team_users_ids, reason=reason)\n \n         raise NotImplementedError(\"Unknown actor type: %r\" % type(actor))\n \n     def bulk_subscribe(\n         self,\n         group: Group,\n-        user_ids: Iterable[int],\n+        user_ids: Iterable[int] | None = None,\n+        team_ids: Iterable[int] | None = None,\n         reason: int = GroupSubscriptionReason.unknown,\n     ) -> bool:\n         \"\"\"\n-        Subscribe a list of user ids to an issue, but only if the users are not explicitly\n+        Subscribe a list of user ids and/or teams to an issue, but only if the users/teams are not explicitly\n         unsubscribed.\n         \"\"\"\n+        from sentry import features\n+\n         # Unique the IDs.\n-        user_ids = set(user_ids)\n+        user_ids = set(user_ids) if user_ids else set()\n+\n+        # Unique the teams.\n+        team_ids = set(team_ids) if team_ids else set()\n \n         # 5 retries for race conditions where\n         # concurrent subscription attempts cause integrity errors\n@@ -117,10 +123,29 @@\n                     is_active=True,\n                     reason=reason,\n                 )\n-                for user_id in user_ids\n-                if user_id not in existing_subscriptions\n+                for user_id in user_ids.difference(existing_subscriptions)\n             ]\n \n+            if features.has(\"organizations:team-workflow-notifications\", group.organization):\n+                existing_team_subscriptions = set(\n+                    GroupSubscription.objects.filter(\n+                        team_id__in=team_ids, group=group, project=group.project\n+                    ).values_list(\"team_id\", flat=True)\n+                )\n+\n+                subscriptions.extend(\n+                    [\n+                        GroupSubscription(\n+                            team_id=team_id,\n+                            group=group,\n+                            project=group.project,\n+                            is_active=True,\n+                            reason=reason,\n+                        )\n+                        for team_id in team_ids.difference(existing_team_subscriptions)\n+                    ]\n+                )\n+\n             try:\n                 with transaction.atomic(router.db_for_write(GroupSubscription)):\n                     self.bulk_create(subscriptions)\n", "issue": "Add subscription for team in `models/groupsubscription`\nTwo updates we need to make here:\r\n1) Update `subscribe_actor` (https://github.com/getsentry/sentry/blob/master/src/sentry/models/groupsubscription.py#L67)  to no longer read all the team's users and just set subscribe the Team\r\n2) Update `bulk_subscribe` to allow for bulk subscribing teams, instead of just users\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING, Iterable, Optional, Sequence, Union\n\nfrom django.conf import settings\nfrom django.db import IntegrityError, models, router, transaction\nfrom django.utils import timezone\n\nfrom sentry.backup.scopes import RelocationScope\nfrom sentry.db.models import (\n    BaseManager,\n    BoundedPositiveIntegerField,\n    FlexibleForeignKey,\n    Model,\n    region_silo_only_model,\n    sane_repr,\n)\nfrom sentry.db.models.fields.hybrid_cloud_foreign_key import HybridCloudForeignKey\nfrom sentry.notifications.helpers import (\n    transform_to_notification_settings_by_recipient,\n    where_should_be_participating,\n)\nfrom sentry.notifications.types import GroupSubscriptionReason, NotificationSettingTypes\nfrom sentry.services.hybrid_cloud.actor import RpcActor\nfrom sentry.services.hybrid_cloud.notifications import notifications_service\nfrom sentry.services.hybrid_cloud.user import RpcUser\n\nif TYPE_CHECKING:\n    from sentry.models import Group, Team, User\n    from sentry.notifications.utils.participants import ParticipantMap\n\n\nclass GroupSubscriptionManager(BaseManager):\n    def subscribe(\n        self,\n        group: Group,\n        subscriber: User | RpcUser | Team,\n        reason: int = GroupSubscriptionReason.unknown,\n    ) -> bool:\n        \"\"\"\n        Subscribe a user or team to an issue, but only if that user or team has not explicitly\n        unsubscribed.\n        \"\"\"\n        from sentry.models import Team, User\n\n        try:\n            with transaction.atomic(router.db_for_write(GroupSubscription)):\n                if isinstance(subscriber, (User, RpcUser)):\n                    self.create(\n                        user_id=subscriber.id,\n                        group=group,\n                        project=group.project,\n                        is_active=True,\n                        reason=reason,\n                    )\n                elif isinstance(subscriber, Team):\n                    self.create(\n                        team=subscriber,\n                        group=group,\n                        project=group.project,\n                        is_active=True,\n                        reason=reason,\n                    )\n        except IntegrityError:\n            pass\n        return True\n\n    def subscribe_actor(\n        self,\n        group: Group,\n        actor: Union[Team, User, RpcUser],\n        reason: int = GroupSubscriptionReason.unknown,\n    ) -> Optional[bool]:\n        from sentry import features\n        from sentry.models import Team, User\n\n        if isinstance(actor, (RpcUser, User)):\n            return self.subscribe(group, actor, reason)\n        if isinstance(actor, Team):\n            if features.has(\"organizations:team-workflow-notifications\", group.organization):\n                return self.subscribe(group, actor, reason)\n            else:\n                # subscribe the members of the team\n                team_users_ids = list(actor.member_set.values_list(\"user_id\", flat=True))\n                return self.bulk_subscribe(group, team_users_ids, reason)\n\n        raise NotImplementedError(\"Unknown actor type: %r\" % type(actor))\n\n    def bulk_subscribe(\n        self,\n        group: Group,\n        user_ids: Iterable[int],\n        reason: int = GroupSubscriptionReason.unknown,\n    ) -> bool:\n        \"\"\"\n        Subscribe a list of user ids to an issue, but only if the users are not explicitly\n        unsubscribed.\n        \"\"\"\n        # Unique the IDs.\n        user_ids = set(user_ids)\n\n        # 5 retries for race conditions where\n        # concurrent subscription attempts cause integrity errors\n        for i in range(4, -1, -1):  # 4 3 2 1 0\n\n            existing_subscriptions = set(\n                GroupSubscription.objects.filter(\n                    user_id__in=user_ids, group=group, project=group.project\n                ).values_list(\"user_id\", flat=True)\n            )\n\n            subscriptions = [\n                GroupSubscription(\n                    user_id=user_id,\n                    group=group,\n                    project=group.project,\n                    is_active=True,\n                    reason=reason,\n                )\n                for user_id in user_ids\n                if user_id not in existing_subscriptions\n            ]\n\n            try:\n                with transaction.atomic(router.db_for_write(GroupSubscription)):\n                    self.bulk_create(subscriptions)\n                    return True\n            except IntegrityError as e:\n                if i == 0:\n                    raise e\n        return False\n\n    def get_participants(self, group: Group) -> ParticipantMap:\n        \"\"\"\n        Identify all users who are participating with a given issue.\n        :param group: Group object\n        \"\"\"\n        from sentry.notifications.utils.participants import ParticipantMap\n\n        all_possible_users = RpcActor.many_from_object(group.project.get_members_as_rpc_users())\n        active_and_disabled_subscriptions = self.filter(\n            group=group, user_id__in=[u.id for u in all_possible_users]\n        )\n\n        notification_settings = notifications_service.get_settings_for_recipient_by_parent(\n            type=NotificationSettingTypes.WORKFLOW,\n            recipients=all_possible_users,\n            parent_id=group.project_id,\n        )\n        subscriptions_by_user_id = {\n            subscription.user_id: subscription for subscription in active_and_disabled_subscriptions\n        }\n        notification_settings_by_recipient = transform_to_notification_settings_by_recipient(\n            notification_settings, all_possible_users\n        )\n\n        result = ParticipantMap()\n        for user in all_possible_users:\n            subscription_option = subscriptions_by_user_id.get(user.id)\n            providers = where_should_be_participating(\n                user,\n                subscription_option,\n                notification_settings_by_recipient,\n            )\n            for provider in providers:\n                reason = (\n                    subscription_option\n                    and subscription_option.reason\n                    or GroupSubscriptionReason.implicit\n                )\n                result.add(provider, user, reason)\n\n        return result\n\n    @staticmethod\n    def get_participating_user_ids(group: Group) -> Sequence[int]:\n        \"\"\"Return the list of user ids participating in this issue.\"\"\"\n\n        return list(\n            GroupSubscription.objects.filter(group=group, is_active=True).values_list(\n                \"user_id\", flat=True\n            )\n        )\n\n\n@region_silo_only_model\nclass GroupSubscription(Model):\n    \"\"\"\n    Identifies a subscription relationship between a user and an issue.\n    \"\"\"\n\n    __relocation_scope__ = RelocationScope.Excluded\n\n    project = FlexibleForeignKey(\"sentry.Project\", related_name=\"subscription_set\")\n    group = FlexibleForeignKey(\"sentry.Group\", related_name=\"subscription_set\")\n    user_id = HybridCloudForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=\"CASCADE\")\n    team = FlexibleForeignKey(\"sentry.Team\", null=True, db_index=True, on_delete=models.CASCADE)\n    is_active = models.BooleanField(default=True)\n    reason = BoundedPositiveIntegerField(default=GroupSubscriptionReason.unknown)\n    date_added = models.DateTimeField(default=timezone.now, null=True)\n\n    objects = GroupSubscriptionManager()\n\n    class Meta:\n        app_label = \"sentry\"\n        db_table = \"sentry_groupsubscription\"\n        unique_together = ((\"group\", \"user_id\"), (\"group\", \"team\"))\n        constraints = [\n            models.CheckConstraint(\n                check=models.Q(team_id__isnull=False, user_id__isnull=True)\n                | models.Q(team_id__isnull=True, user_id__isnull=False),\n                name=\"subscription_team_or_user_check\",\n            )\n        ]\n\n    __repr__ = sane_repr(\"project_id\", \"group_id\", \"user_id\")\n", "path": "src/sentry/models/groupsubscription.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING, Iterable, Optional, Sequence, Union\n\nfrom django.conf import settings\nfrom django.db import IntegrityError, models, router, transaction\nfrom django.utils import timezone\n\nfrom sentry.backup.scopes import RelocationScope\nfrom sentry.db.models import (\n    BaseManager,\n    BoundedPositiveIntegerField,\n    FlexibleForeignKey,\n    Model,\n    region_silo_only_model,\n    sane_repr,\n)\nfrom sentry.db.models.fields.hybrid_cloud_foreign_key import HybridCloudForeignKey\nfrom sentry.notifications.helpers import (\n    transform_to_notification_settings_by_recipient,\n    where_should_be_participating,\n)\nfrom sentry.notifications.types import GroupSubscriptionReason, NotificationSettingTypes\nfrom sentry.services.hybrid_cloud.actor import RpcActor\nfrom sentry.services.hybrid_cloud.notifications import notifications_service\nfrom sentry.services.hybrid_cloud.user import RpcUser\n\nif TYPE_CHECKING:\n    from sentry.models import Group, Team, User\n    from sentry.notifications.utils.participants import ParticipantMap\n\n\nclass GroupSubscriptionManager(BaseManager):\n    def subscribe(\n        self,\n        group: Group,\n        subscriber: User | RpcUser | Team,\n        reason: int = GroupSubscriptionReason.unknown,\n    ) -> bool:\n        \"\"\"\n        Subscribe a user or team to an issue, but only if that user or team has not explicitly\n        unsubscribed.\n        \"\"\"\n        from sentry.models import Team, User\n\n        try:\n            with transaction.atomic(router.db_for_write(GroupSubscription)):\n                if isinstance(subscriber, (User, RpcUser)):\n                    self.create(\n                        user_id=subscriber.id,\n                        group=group,\n                        project=group.project,\n                        is_active=True,\n                        reason=reason,\n                    )\n                elif isinstance(subscriber, Team):\n                    self.create(\n                        team=subscriber,\n                        group=group,\n                        project=group.project,\n                        is_active=True,\n                        reason=reason,\n                    )\n        except IntegrityError:\n            pass\n        return True\n\n    def subscribe_actor(\n        self,\n        group: Group,\n        actor: Union[Team, User, RpcUser],\n        reason: int = GroupSubscriptionReason.unknown,\n    ) -> Optional[bool]:\n        from sentry import features\n        from sentry.models import Team, User\n\n        if isinstance(actor, (RpcUser, User)):\n            return self.subscribe(group, actor, reason)\n        if isinstance(actor, Team):\n            if features.has(\"organizations:team-workflow-notifications\", group.organization):\n                return self.subscribe(group, actor, reason)\n            else:\n                # subscribe the members of the team\n                team_users_ids = list(actor.member_set.values_list(\"user_id\", flat=True))\n                return self.bulk_subscribe(group=group, user_ids=team_users_ids, reason=reason)\n\n        raise NotImplementedError(\"Unknown actor type: %r\" % type(actor))\n\n    def bulk_subscribe(\n        self,\n        group: Group,\n        user_ids: Iterable[int] | None = None,\n        team_ids: Iterable[int] | None = None,\n        reason: int = GroupSubscriptionReason.unknown,\n    ) -> bool:\n        \"\"\"\n        Subscribe a list of user ids and/or teams to an issue, but only if the users/teams are not explicitly\n        unsubscribed.\n        \"\"\"\n        from sentry import features\n\n        # Unique the IDs.\n        user_ids = set(user_ids) if user_ids else set()\n\n        # Unique the teams.\n        team_ids = set(team_ids) if team_ids else set()\n\n        # 5 retries for race conditions where\n        # concurrent subscription attempts cause integrity errors\n        for i in range(4, -1, -1):  # 4 3 2 1 0\n\n            existing_subscriptions = set(\n                GroupSubscription.objects.filter(\n                    user_id__in=user_ids, group=group, project=group.project\n                ).values_list(\"user_id\", flat=True)\n            )\n\n            subscriptions = [\n                GroupSubscription(\n                    user_id=user_id,\n                    group=group,\n                    project=group.project,\n                    is_active=True,\n                    reason=reason,\n                )\n                for user_id in user_ids.difference(existing_subscriptions)\n            ]\n\n            if features.has(\"organizations:team-workflow-notifications\", group.organization):\n                existing_team_subscriptions = set(\n                    GroupSubscription.objects.filter(\n                        team_id__in=team_ids, group=group, project=group.project\n                    ).values_list(\"team_id\", flat=True)\n                )\n\n                subscriptions.extend(\n                    [\n                        GroupSubscription(\n                            team_id=team_id,\n                            group=group,\n                            project=group.project,\n                            is_active=True,\n                            reason=reason,\n                        )\n                        for team_id in team_ids.difference(existing_team_subscriptions)\n                    ]\n                )\n\n            try:\n                with transaction.atomic(router.db_for_write(GroupSubscription)):\n                    self.bulk_create(subscriptions)\n                    return True\n            except IntegrityError as e:\n                if i == 0:\n                    raise e\n        return False\n\n    def get_participants(self, group: Group) -> ParticipantMap:\n        \"\"\"\n        Identify all users who are participating with a given issue.\n        :param group: Group object\n        \"\"\"\n        from sentry.notifications.utils.participants import ParticipantMap\n\n        all_possible_users = RpcActor.many_from_object(group.project.get_members_as_rpc_users())\n        active_and_disabled_subscriptions = self.filter(\n            group=group, user_id__in=[u.id for u in all_possible_users]\n        )\n\n        notification_settings = notifications_service.get_settings_for_recipient_by_parent(\n            type=NotificationSettingTypes.WORKFLOW,\n            recipients=all_possible_users,\n            parent_id=group.project_id,\n        )\n        subscriptions_by_user_id = {\n            subscription.user_id: subscription for subscription in active_and_disabled_subscriptions\n        }\n        notification_settings_by_recipient = transform_to_notification_settings_by_recipient(\n            notification_settings, all_possible_users\n        )\n\n        result = ParticipantMap()\n        for user in all_possible_users:\n            subscription_option = subscriptions_by_user_id.get(user.id)\n            providers = where_should_be_participating(\n                user,\n                subscription_option,\n                notification_settings_by_recipient,\n            )\n            for provider in providers:\n                reason = (\n                    subscription_option\n                    and subscription_option.reason\n                    or GroupSubscriptionReason.implicit\n                )\n                result.add(provider, user, reason)\n\n        return result\n\n    @staticmethod\n    def get_participating_user_ids(group: Group) -> Sequence[int]:\n        \"\"\"Return the list of user ids participating in this issue.\"\"\"\n\n        return list(\n            GroupSubscription.objects.filter(group=group, is_active=True).values_list(\n                \"user_id\", flat=True\n            )\n        )\n\n\n@region_silo_only_model\nclass GroupSubscription(Model):\n    \"\"\"\n    Identifies a subscription relationship between a user and an issue.\n    \"\"\"\n\n    __relocation_scope__ = RelocationScope.Excluded\n\n    project = FlexibleForeignKey(\"sentry.Project\", related_name=\"subscription_set\")\n    group = FlexibleForeignKey(\"sentry.Group\", related_name=\"subscription_set\")\n    user_id = HybridCloudForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=\"CASCADE\")\n    team = FlexibleForeignKey(\"sentry.Team\", null=True, db_index=True, on_delete=models.CASCADE)\n    is_active = models.BooleanField(default=True)\n    reason = BoundedPositiveIntegerField(default=GroupSubscriptionReason.unknown)\n    date_added = models.DateTimeField(default=timezone.now, null=True)\n\n    objects = GroupSubscriptionManager()\n\n    class Meta:\n        app_label = \"sentry\"\n        db_table = \"sentry_groupsubscription\"\n        unique_together = ((\"group\", \"user_id\"), (\"group\", \"team\"))\n        constraints = [\n            models.CheckConstraint(\n                check=models.Q(team_id__isnull=False, user_id__isnull=True)\n                | models.Q(team_id__isnull=True, user_id__isnull=False),\n                name=\"subscription_team_or_user_check\",\n            )\n        ]\n\n    __repr__ = sane_repr(\"project_id\", \"group_id\", \"user_id\")\n", "path": "src/sentry/models/groupsubscription.py"}]}