We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
imports get stuck when server is restarted

* begin importing channel
* stop server
* start server

Transfer is stuck partway. It does not continue, and due to #1673 cannot be canceled:

![image](https://user-images.githubusercontent.com/2367265/27461544-370a8796-576f-11e7-8e64-86fb3562d304.png)



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kolibri/tasks/api.py`
Content:
```
1 import logging as logger
2 
3 from django.apps.registry import AppRegistryNotReady
4 
5 try:
6     from django.apps import apps
7 
8     apps.check_apps_ready()
9 except AppRegistryNotReady:
10     import django
11 
12     django.setup()
13 
14 import requests
15 from django.core.management import call_command
16 from django.conf import settings
17 from django.http import Http404
18 from django.utils.translation import ugettext as _
19 from kolibri.content.models import ChannelMetadataCache
20 from kolibri.content.utils.channels import get_mounted_drives_with_channel_info
21 from kolibri.content.utils.paths import get_content_database_file_url
22 from rest_framework import serializers, viewsets
23 from rest_framework.decorators import list_route
24 from rest_framework.response import Response
25 from barbequeue.common.classes import State
26 from barbequeue.client import SimpleClient
27 
28 from .permissions import IsDeviceOwnerOnly
29 
30 logging = logger.getLogger(__name__)
31 
32 client = SimpleClient(
33     app="kolibri", storage_path=settings.QUEUE_JOB_STORAGE_PATH)
34 
35 # all tasks are marked as remote imports for nwo
36 TASKTYPE = "remoteimport"
37 
38 
39 class TasksViewSet(viewsets.ViewSet):
40     permission_classes = (IsDeviceOwnerOnly, )
41 
42     def list(self, request):
43         jobs_response = [_job_to_response(j) for j in client.all_jobs()]
44         return Response(jobs_response)
45 
46     def create(self, request):
47         # unimplemented. Call out to the task-specific APIs for now.
48         pass
49 
50     def retrieve(self, request, pk=None):
51         task = _job_to_response(client.status(pk))
52         return Response(task)
53 
54     def destroy(self, request, pk=None):
55         # unimplemented for now.
56         pass
57 
58     @list_route(methods=['post'])
59     def startremoteimport(self, request):
60         '''Download a channel's database from the main curation server, and then
61         download its content.
62 
63         '''
64 
65         if "channel_id" not in request.data:
66             raise serializers.ValidationError(
67                 "The 'channel_id' field is required.")
68 
69         channel_id = request.data['channel_id']
70 
71         # ensure the requested channel_id can be found on the central server, otherwise error
72         status = requests.head(
73             get_content_database_file_url(channel_id)).status_code
74         if status == 404:
75             raise Http404(
76                 _("The requested channel does not exist on the content server")
77             )
78 
79         task_id = client.schedule(
80             _networkimport, channel_id, track_progress=True)
81 
82         # attempt to get the created Task, otherwise return pending status
83         resp = _job_to_response(client.status(task_id))
84 
85         return Response(resp)
86 
87     @list_route(methods=['post'])
88     def startlocalimport(self, request):
89         """
90         Import a channel from a local drive, and copy content to the local machine.
91         """
92         # Importing django/running setup because Windows...
93 
94         if "drive_id" not in request.data:
95             raise serializers.ValidationError(
96                 "The 'drive_id' field is required.")
97 
98         job_id = client.schedule(
99             _localimport, request.data['drive_id'], track_progress=True)
100 
101         # attempt to get the created Task, otherwise return pending status
102         resp = _job_to_response(client.status(job_id))
103 
104         return Response(resp)
105 
106     @list_route(methods=['post'])
107     def startlocalexport(self, request):
108         '''
109         Export a channel to a local drive, and copy content to the drive.
110 
111         '''
112 
113         if "drive_id" not in request.data:
114             raise serializers.ValidationError(
115                 "The 'drive_id' field is required.")
116 
117         job_id = client.schedule(
118             _localexport, request.data['drive_id'], track_progress=True)
119 
120         # attempt to get the created Task, otherwise return pending status
121         resp = _job_to_response(client.status(job_id))
122 
123         return Response(resp)
124 
125     @list_route(methods=['post'])
126     def cleartask(self, request):
127         '''
128         Clears a task with its task id given in the task_id parameter.
129         '''
130 
131         if 'task_id' not in request.data:
132             raise serializers.ValidationError(
133                 "The 'task_id' field is required.")
134 
135         client.clear(force=True)
136         return Response({})
137 
138     @list_route(methods=['get'])
139     def localdrive(self, request):
140         drives = get_mounted_drives_with_channel_info()
141 
142         # make sure everything is a dict, before converting to JSON
143         assert isinstance(drives, dict)
144         out = [mountdata._asdict() for mountdata in drives.values()]
145 
146         return Response(out)
147 
148 
149 def _networkimport(channel_id, update_progress=None):
150     call_command("importchannel", "network", channel_id)
151     call_command(
152         "importcontent",
153         "network",
154         channel_id,
155         update_progress=update_progress)
156 
157 
158 def _localimport(drive_id, update_progress=None):
159     drives = get_mounted_drives_with_channel_info()
160     drive = drives[drive_id]
161     for channel in drive.metadata["channels"]:
162         call_command("importchannel", "local", channel["id"], drive.datafolder)
163         call_command(
164             "importcontent",
165             "local",
166             channel["id"],
167             drive.datafolder,
168             update_progress=update_progress)
169 
170 
171 def _localexport(drive_id, update_progress=None):
172     drives = get_mounted_drives_with_channel_info()
173     drive = drives[drive_id]
174     for channel in ChannelMetadataCache.objects.all():
175         call_command("exportchannel", channel.id, drive.datafolder)
176         call_command(
177             "exportcontent",
178             channel.id,
179             drive.datafolder,
180             update_progress=update_progress)
181 
182 
183 def _job_to_response(job):
184     if not job:
185         return {
186             "type": TASKTYPE,
187             "status": State.SCHEDULED,
188             "percentage": 0,
189             "progress": [],
190             "id": job.job_id,
191         }
192     else:
193         return {
194             "type": TASKTYPE,
195             "status": job.state,
196             "exception": str(job.exception),
197             "traceback": str(job.traceback),
198             "percentage": job.percentage_progress,
199             "id": job.job_id,
200         }
201
```
--- 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/kolibri/tasks/api.py b/kolibri/tasks/api.py
--- a/kolibri/tasks/api.py
+++ b/kolibri/tasks/api.py
@@ -13,7 +13,6 @@
 
 import requests
 from django.core.management import call_command
-from django.conf import settings
 from django.http import Http404
 from django.utils.translation import ugettext as _
 from kolibri.content.models import ChannelMetadataCache
@@ -29,15 +28,14 @@
 
 logging = logger.getLogger(__name__)
 
-client = SimpleClient(
-    app="kolibri", storage_path=settings.QUEUE_JOB_STORAGE_PATH)
+client = SimpleClient(app="kolibri")
 
 # all tasks are marked as remote imports for nwo
 TASKTYPE = "remoteimport"
 
 
 class TasksViewSet(viewsets.ViewSet):
-    permission_classes = (IsDeviceOwnerOnly, )
+    permission_classes = (IsDeviceOwnerOnly,)
 
     def list(self, request):
         jobs_response = [_job_to_response(j) for j in client.all_jobs()]

{"golden_diff": "diff --git a/kolibri/tasks/api.py b/kolibri/tasks/api.py\n--- a/kolibri/tasks/api.py\n+++ b/kolibri/tasks/api.py\n@@ -13,7 +13,6 @@\n \n import requests\n from django.core.management import call_command\n-from django.conf import settings\n from django.http import Http404\n from django.utils.translation import ugettext as _\n from kolibri.content.models import ChannelMetadataCache\n@@ -29,15 +28,14 @@\n \n logging = logger.getLogger(__name__)\n \n-client = SimpleClient(\n-    app=\"kolibri\", storage_path=settings.QUEUE_JOB_STORAGE_PATH)\n+client = SimpleClient(app=\"kolibri\")\n \n # all tasks are marked as remote imports for nwo\n TASKTYPE = \"remoteimport\"\n \n \n class TasksViewSet(viewsets.ViewSet):\n-    permission_classes = (IsDeviceOwnerOnly, )\n+    permission_classes = (IsDeviceOwnerOnly,)\n \n     def list(self, request):\n         jobs_response = [_job_to_response(j) for j in client.all_jobs()]\n", "issue": "imports get stuck when server is restarted\n\r\n* begin importing channel\r\n* stop server\r\n* start server\r\n\r\nTransfer is stuck partway. It does not continue, and due to #1673 cannot be canceled:\r\n\r\n![image](https://user-images.githubusercontent.com/2367265/27461544-370a8796-576f-11e7-8e64-86fb3562d304.png)\r\n\r\n\n", "before_files": [{"content": "import logging as logger\n\nfrom django.apps.registry import AppRegistryNotReady\n\ntry:\n    from django.apps import apps\n\n    apps.check_apps_ready()\nexcept AppRegistryNotReady:\n    import django\n\n    django.setup()\n\nimport requests\nfrom django.core.management import call_command\nfrom django.conf import settings\nfrom django.http import Http404\nfrom django.utils.translation import ugettext as _\nfrom kolibri.content.models import ChannelMetadataCache\nfrom kolibri.content.utils.channels import get_mounted_drives_with_channel_info\nfrom kolibri.content.utils.paths import get_content_database_file_url\nfrom rest_framework import serializers, viewsets\nfrom rest_framework.decorators import list_route\nfrom rest_framework.response import Response\nfrom barbequeue.common.classes import State\nfrom barbequeue.client import SimpleClient\n\nfrom .permissions import IsDeviceOwnerOnly\n\nlogging = logger.getLogger(__name__)\n\nclient = SimpleClient(\n    app=\"kolibri\", storage_path=settings.QUEUE_JOB_STORAGE_PATH)\n\n# all tasks are marked as remote imports for nwo\nTASKTYPE = \"remoteimport\"\n\n\nclass TasksViewSet(viewsets.ViewSet):\n    permission_classes = (IsDeviceOwnerOnly, )\n\n    def list(self, request):\n        jobs_response = [_job_to_response(j) for j in client.all_jobs()]\n        return Response(jobs_response)\n\n    def create(self, request):\n        # unimplemented. Call out to the task-specific APIs for now.\n        pass\n\n    def retrieve(self, request, pk=None):\n        task = _job_to_response(client.status(pk))\n        return Response(task)\n\n    def destroy(self, request, pk=None):\n        # unimplemented for now.\n        pass\n\n    @list_route(methods=['post'])\n    def startremoteimport(self, request):\n        '''Download a channel's database from the main curation server, and then\n        download its content.\n\n        '''\n\n        if \"channel_id\" not in request.data:\n            raise serializers.ValidationError(\n                \"The 'channel_id' field is required.\")\n\n        channel_id = request.data['channel_id']\n\n        # ensure the requested channel_id can be found on the central server, otherwise error\n        status = requests.head(\n            get_content_database_file_url(channel_id)).status_code\n        if status == 404:\n            raise Http404(\n                _(\"The requested channel does not exist on the content server\")\n            )\n\n        task_id = client.schedule(\n            _networkimport, channel_id, track_progress=True)\n\n        # attempt to get the created Task, otherwise return pending status\n        resp = _job_to_response(client.status(task_id))\n\n        return Response(resp)\n\n    @list_route(methods=['post'])\n    def startlocalimport(self, request):\n        \"\"\"\n        Import a channel from a local drive, and copy content to the local machine.\n        \"\"\"\n        # Importing django/running setup because Windows...\n\n        if \"drive_id\" not in request.data:\n            raise serializers.ValidationError(\n                \"The 'drive_id' field is required.\")\n\n        job_id = client.schedule(\n            _localimport, request.data['drive_id'], track_progress=True)\n\n        # attempt to get the created Task, otherwise return pending status\n        resp = _job_to_response(client.status(job_id))\n\n        return Response(resp)\n\n    @list_route(methods=['post'])\n    def startlocalexport(self, request):\n        '''\n        Export a channel to a local drive, and copy content to the drive.\n\n        '''\n\n        if \"drive_id\" not in request.data:\n            raise serializers.ValidationError(\n                \"The 'drive_id' field is required.\")\n\n        job_id = client.schedule(\n            _localexport, request.data['drive_id'], track_progress=True)\n\n        # attempt to get the created Task, otherwise return pending status\n        resp = _job_to_response(client.status(job_id))\n\n        return Response(resp)\n\n    @list_route(methods=['post'])\n    def cleartask(self, request):\n        '''\n        Clears a task with its task id given in the task_id parameter.\n        '''\n\n        if 'task_id' not in request.data:\n            raise serializers.ValidationError(\n                \"The 'task_id' field is required.\")\n\n        client.clear(force=True)\n        return Response({})\n\n    @list_route(methods=['get'])\n    def localdrive(self, request):\n        drives = get_mounted_drives_with_channel_info()\n\n        # make sure everything is a dict, before converting to JSON\n        assert isinstance(drives, dict)\n        out = [mountdata._asdict() for mountdata in drives.values()]\n\n        return Response(out)\n\n\ndef _networkimport(channel_id, update_progress=None):\n    call_command(\"importchannel\", \"network\", channel_id)\n    call_command(\n        \"importcontent\",\n        \"network\",\n        channel_id,\n        update_progress=update_progress)\n\n\ndef _localimport(drive_id, update_progress=None):\n    drives = get_mounted_drives_with_channel_info()\n    drive = drives[drive_id]\n    for channel in drive.metadata[\"channels\"]:\n        call_command(\"importchannel\", \"local\", channel[\"id\"], drive.datafolder)\n        call_command(\n            \"importcontent\",\n            \"local\",\n            channel[\"id\"],\n            drive.datafolder,\n            update_progress=update_progress)\n\n\ndef _localexport(drive_id, update_progress=None):\n    drives = get_mounted_drives_with_channel_info()\n    drive = drives[drive_id]\n    for channel in ChannelMetadataCache.objects.all():\n        call_command(\"exportchannel\", channel.id, drive.datafolder)\n        call_command(\n            \"exportcontent\",\n            channel.id,\n            drive.datafolder,\n            update_progress=update_progress)\n\n\ndef _job_to_response(job):\n    if not job:\n        return {\n            \"type\": TASKTYPE,\n            \"status\": State.SCHEDULED,\n            \"percentage\": 0,\n            \"progress\": [],\n            \"id\": job.job_id,\n        }\n    else:\n        return {\n            \"type\": TASKTYPE,\n            \"status\": job.state,\n            \"exception\": str(job.exception),\n            \"traceback\": str(job.traceback),\n            \"percentage\": job.percentage_progress,\n            \"id\": job.job_id,\n        }\n", "path": "kolibri/tasks/api.py"}], "after_files": [{"content": "import logging as logger\n\nfrom django.apps.registry import AppRegistryNotReady\n\ntry:\n    from django.apps import apps\n\n    apps.check_apps_ready()\nexcept AppRegistryNotReady:\n    import django\n\n    django.setup()\n\nimport requests\nfrom django.core.management import call_command\nfrom django.http import Http404\nfrom django.utils.translation import ugettext as _\nfrom kolibri.content.models import ChannelMetadataCache\nfrom kolibri.content.utils.channels import get_mounted_drives_with_channel_info\nfrom kolibri.content.utils.paths import get_content_database_file_url\nfrom rest_framework import serializers, viewsets\nfrom rest_framework.decorators import list_route\nfrom rest_framework.response import Response\nfrom barbequeue.common.classes import State\nfrom barbequeue.client import SimpleClient\n\nfrom .permissions import IsDeviceOwnerOnly\n\nlogging = logger.getLogger(__name__)\n\nclient = SimpleClient(app=\"kolibri\")\n\n# all tasks are marked as remote imports for nwo\nTASKTYPE = \"remoteimport\"\n\n\nclass TasksViewSet(viewsets.ViewSet):\n    permission_classes = (IsDeviceOwnerOnly,)\n\n    def list(self, request):\n        jobs_response = [_job_to_response(j) for j in client.all_jobs()]\n        return Response(jobs_response)\n\n    def create(self, request):\n        # unimplemented. Call out to the task-specific APIs for now.\n        pass\n\n    def retrieve(self, request, pk=None):\n        task = _job_to_response(client.status(pk))\n        return Response(task)\n\n    def destroy(self, request, pk=None):\n        # unimplemented for now.\n        pass\n\n    @list_route(methods=['post'])\n    def startremoteimport(self, request):\n        '''Download a channel's database from the main curation server, and then\n        download its content.\n\n        '''\n\n        if \"channel_id\" not in request.data:\n            raise serializers.ValidationError(\n                \"The 'channel_id' field is required.\")\n\n        channel_id = request.data['channel_id']\n\n        # ensure the requested channel_id can be found on the central server, otherwise error\n        status = requests.head(\n            get_content_database_file_url(channel_id)).status_code\n        if status == 404:\n            raise Http404(\n                _(\"The requested channel does not exist on the content server\")\n            )\n\n        task_id = client.schedule(\n            _networkimport, channel_id, track_progress=True)\n\n        # attempt to get the created Task, otherwise return pending status\n        resp = _job_to_response(client.status(task_id))\n\n        return Response(resp)\n\n    @list_route(methods=['post'])\n    def startlocalimport(self, request):\n        \"\"\"\n        Import a channel from a local drive, and copy content to the local machine.\n        \"\"\"\n        # Importing django/running setup because Windows...\n\n        if \"drive_id\" not in request.data:\n            raise serializers.ValidationError(\n                \"The 'drive_id' field is required.\")\n\n        job_id = client.schedule(\n            _localimport, request.data['drive_id'], track_progress=True)\n\n        # attempt to get the created Task, otherwise return pending status\n        resp = _job_to_response(client.status(job_id))\n\n        return Response(resp)\n\n    @list_route(methods=['post'])\n    def startlocalexport(self, request):\n        '''\n        Export a channel to a local drive, and copy content to the drive.\n\n        '''\n\n        if \"drive_id\" not in request.data:\n            raise serializers.ValidationError(\n                \"The 'drive_id' field is required.\")\n\n        job_id = client.schedule(\n            _localexport, request.data['drive_id'], track_progress=True)\n\n        # attempt to get the created Task, otherwise return pending status\n        resp = _job_to_response(client.status(job_id))\n\n        return Response(resp)\n\n    @list_route(methods=['post'])\n    def cleartask(self, request):\n        '''\n        Clears a task with its task id given in the task_id parameter.\n        '''\n\n        if 'task_id' not in request.data:\n            raise serializers.ValidationError(\n                \"The 'task_id' field is required.\")\n\n        client.clear(force=True)\n        return Response({})\n\n    @list_route(methods=['get'])\n    def localdrive(self, request):\n        drives = get_mounted_drives_with_channel_info()\n\n        # make sure everything is a dict, before converting to JSON\n        assert isinstance(drives, dict)\n        out = [mountdata._asdict() for mountdata in drives.values()]\n\n        return Response(out)\n\n\ndef _networkimport(channel_id, update_progress=None):\n    call_command(\"importchannel\", \"network\", channel_id)\n    call_command(\n        \"importcontent\",\n        \"network\",\n        channel_id,\n        update_progress=update_progress)\n\n\ndef _localimport(drive_id, update_progress=None):\n    drives = get_mounted_drives_with_channel_info()\n    drive = drives[drive_id]\n    for channel in drive.metadata[\"channels\"]:\n        call_command(\"importchannel\", \"local\", channel[\"id\"], drive.datafolder)\n        call_command(\n            \"importcontent\",\n            \"local\",\n            channel[\"id\"],\n            drive.datafolder,\n            update_progress=update_progress)\n\n\ndef _localexport(drive_id, update_progress=None):\n    drives = get_mounted_drives_with_channel_info()\n    drive = drives[drive_id]\n    for channel in ChannelMetadataCache.objects.all():\n        call_command(\"exportchannel\", channel.id, drive.datafolder)\n        call_command(\n            \"exportcontent\",\n            channel.id,\n            drive.datafolder,\n            update_progress=update_progress)\n\n\ndef _job_to_response(job):\n    if not job:\n        return {\n            \"type\": TASKTYPE,\n            \"status\": State.SCHEDULED,\n            \"percentage\": 0,\n            \"progress\": [],\n            \"id\": job.job_id,\n        }\n    else:\n        return {\n            \"type\": TASKTYPE,\n            \"status\": job.state,\n            \"exception\": str(job.exception),\n            \"traceback\": str(job.traceback),\n            \"percentage\": job.percentage_progress,\n            \"id\": job.job_id,\n        }\n", "path": "kolibri/tasks/api.py"}]}