Repository: hydroshare/hydroshare

Issue:
REST request for zip download of aggregation often hangs
**Description of the bug**
When using hsclient to download an aggregation, the download request often hangs as the celery task in hydroshare does not return a success/finished status to hsclient. This is probably a bug in hydroshare. 

Steps to reproduce the bug:
1. Create an aggregation in hydroshare.
2. Then use hsclient to download that aggregation. Try downloading the aggregation couple of times and you should see the download does not work every time.


**Expected behavior**
When downloading an aggregation using hsclient the download should be successful.

**Additional information**
Add any other context about the problem here such as screenshots, software versions, and browser information.



Discussion:

Resolving patch:
diff --git a/django_irods/views.py b/django_irods/views.py
--- a/django_irods/views.py
+++ b/django_irods/views.py
@@ -3,7 +3,6 @@
 import os
 import urllib
 from uuid import uuid4
-from celery.result import AsyncResult
 
 from django.conf import settings
 from django.http import HttpResponse, FileResponse, HttpResponseRedirect, JsonResponse
@@ -12,7 +11,12 @@
 
 from django_irods import icommands
 from hs_core.hydroshare.resource import check_resource_type
-from hs_core.task_utils import get_resource_bag_task, get_or_create_task_notification, get_task_user_id
+from hs_core.task_utils import (
+    get_resource_bag_task,
+    get_or_create_task_notification,
+    get_task_user_id,
+    get_task_notification
+)
 
 from hs_core.signals import pre_download_file, pre_check_bag_flag
 from hs_core.tasks import create_bag_by_irods, create_temp_zip, delete_zip
@@ -380,16 +384,14 @@ def rest_check_task_status(request, task_id, *args, **kwargs):
     '''
     if not task_id:
         task_id = request.POST.get('task_id')
-    result = AsyncResult(task_id)
-    if result.ready():
-        try:
-            ret_value = result.get()
-            return JsonResponse({"status": 'true',
-                                 'payload': str(ret_value)})
-        # use the Broad scope Exception to catch all exception types since this view function can be used for all tasks
-        except Exception:
-            # logging exception will log the full stack trace and prepend a line with the message str input argument
-            logger.exception('An exception is raised from task {}'.format(task_id))
+    task_notification = get_task_notification(task_id)
+    if task_notification:
+        n_status = task_notification['status']
+        if n_status in ['completed', 'delivered']:
+            return JsonResponse({"status": 'true', 'payload': task_notification['payload']})
+        if n_status == 'progress':
+            return JsonResponse({"status": 'false'})
+        if n_status in ['failed', 'aborted']:
             return JsonResponse({"status": 'false'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
     else:
         return JsonResponse({"status": None})
diff --git a/hs_core/task_utils.py b/hs_core/task_utils.py
--- a/hs_core/task_utils.py
+++ b/hs_core/task_utils.py
@@ -89,6 +89,20 @@ def get_or_create_task_notification(task_id, status='progress', name='', payload
         }
 
 
+def get_task_notification(task_id):
+    try:
+        obj = TaskNotification.objects.get(task_id=task_id)
+
+        return {
+            'id': task_id,
+            'name': obj.name,
+            'status': obj.status,
+            'payload': obj.payload
+        }
+    except TaskNotification.DoesNotExist:
+        return None
+
+
 def get_resource_bag_task(res_id):
     job_name = 'hs_core.tasks.create_bag_by_irods'
     return _retrieve_job_id(job_name, res_id)


Test patch: