From 73bc3ac422d9018929c12804e393664e1146b787 Mon Sep 17 00:00:00 2001 From: Francisco Trivino Date: Wed, 2 Oct 2024 19:02:34 +0200 Subject: [PATCH] Fix delay in integration domain addition This commit extends the domain views to eliminate the response wait time on the client by returning the HTTP 202 Accepted status code. This change allows the request to be processed asynchronously, preventing client-side timeouts due to longer domain addition tasks. Fixes: https://github.com/freeipa/ipa-tuura/issues/138 Signed-off-by: Francisco Trivino --- src/ipa-tuura/domains/views.py | 59 +++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/ipa-tuura/domains/views.py b/src/ipa-tuura/domains/views.py index d89f6b8..2b399b1 100644 --- a/src/ipa-tuura/domains/views.py +++ b/src/ipa-tuura/domains/views.py @@ -3,6 +3,7 @@ # import logging +import threading from django.http import Http404 from domains.adapters import DomainSerializer @@ -38,20 +39,26 @@ def create(self, request, *args, **kwargs): serializer.is_valid(raise_exception=True) logger.info(f"domain create {serializer.validated_data}") - try: - add_domain(serializer.validated_data) - except RuntimeError as e: - return Response(str(e), status=status.HTTP_405_METHOD_NOT_ALLOWED) - except Exception as e: - raise e - else: - self.perform_create(serializer) + # Define the background process for handling the domain addition + def process_domain_creation(): + try: + add_domain(serializer.validated_data) + except Exception as e: + logger.error(f"Unexpected error during domain creation: {str(e)}") + raise e + else: + self.perform_create(serializer) - # reset the writable interface - ipa = IPA() - ipa._reset_instance() + # reset the writable interface + ipa = IPA() + ipa._reset_instance() - return Response(serializer.data, status=status.HTTP_201_CREATED) + # Run the domain creation logic in a separate thread + thread = threading.Thread(target=process_domain_creation) + thread.start() + + # Return the created response + return Response(serializer.validated_data, status=status.HTTP_202_ACCEPTED) # handles GETs for 1 Domain def retrieve(self, request, *args, **kwargs): @@ -77,13 +84,21 @@ def list(self, request, *args, **kwargs): # handles DELETEs for 1 Domain def destroy(self, request, *args, **kwargs): - try: - instance = self.get_object() - serializer = self.get_serializer(instance) - logger.info(f"domain destroy {serializer.data}") - delete_domain(serializer.data) - self.perform_destroy(instance) - except Http404: - pass - - return Response(status=status.HTTP_204_NO_CONTENT) + + # Define the background process for handling the domain destroy + def process_domain_destroy(): + try: + instance = self.get_object() + serializer = self.get_serializer(instance) + logger.info(f"domain destroy {serializer.data}") + delete_domain(serializer.data) + self.perform_destroy(instance) + except Exception as e: + logger.error(f"Unexpected error during domain destroy: {str(e)}") + raise e + + # Run the domain destroy logic in a separate thread + thread = threading.Thread(target=process_domain_destroy) + thread.start() + + return Response(status=status.HTTP_202_ACCEPTED)