Skip to content

Commit

Permalink
Asynchronously propagate permissions to avoid internal server errors
Browse files Browse the repository at this point in the history
- Avoids 500 status codes when trying to reach the External KPI service
  due to network issues or unexpected service unavailability
  • Loading branch information
DavisRayM committed Nov 24, 2022
1 parent df75c2b commit 5d36038
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
5 changes: 3 additions & 2 deletions onadata/libs/models/share_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
EditorMinorRole, EditorRole)
from onadata.libs.utils.cache_tools import (PROJ_OWNER_CACHE, PROJ_PERM_CACHE,
safe_delete)
from onadata.libs.utils.project_utils import propagate_project_permissions
from onadata.libs.utils.project_utils import \
propagate_project_permissions_async

# pylint: disable=invalid-name
User = get_user_model()
Expand Down Expand Up @@ -86,7 +87,7 @@ def save(self, **kwargs):
safe_delete(f"{PROJ_PERM_CACHE}{self.project.pk}")

# propagate permissions
propagate_project_permissions(self.project)
propagate_project_permissions_async.apply_async(args=[self.project.pk])

@transaction.atomic()
def __remove_user(self):
Expand Down
14 changes: 14 additions & 0 deletions onadata/libs/utils/project_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,20 @@ def assign_change_asset_permission(
)
return resp

@app.task(bind=True, max_retries=3)
def propagate_project_permissions_async(self, project_id: int, headers: Optional[dict] = None, use_asset_owner_auth: bool = True):
"""
Asynchronously propagates Project Permissions to the Formbuilder assets within the project
"""
try:
project = Project.objects.get(id=project_id)
propagate_project_permissions(project, headers, use_asset_owner_auth)
except (Project.DoesNotExist, ExternalServiceRequestError) as e:
if self.request.retries > 3:
msg = f"Failed to propagate asset permissions for Project {project_id}"
report_exception(msg, e, sys.exc_info())
self.retry(exc=e, countdown=60 * self.request.retries)


def propagate_project_permissions(
project: Project, headers: Optional[dict] = None, use_asset_owner_auth: bool = True
Expand Down

0 comments on commit 5d36038

Please sign in to comment.