Skip to content

Commit 4743786

Browse files
committed
collectionviews: Synchronize concurrent ensure_initiated functions
It is possible for concurrent requests to be served by different threads in the same Python process, resulting in unexpected behaviour if the wrapper function from ensure_initiated is not finished executing for the first time. To solve this, wrap the critical code in a lock. https://phabricator.endlessm.com/T35159
1 parent 8542bd1 commit 4743786

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

kolibri_explore_plugin/collectionviews.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import time
77
from enum import auto
88
from enum import IntEnum
9+
from threading import RLock
910

1011
from django.utils.translation import gettext_lazy as _
1112
from kolibri.core.content.errors import InsufficientStorageSpaceError
@@ -72,6 +73,8 @@
7273
"completed": 1,
7374
}
7475

76+
ENSURE_INITIATED_RLOCK = RLock()
77+
7578

7679
class ChannelNotImported(Exception):
7780
pass
@@ -763,8 +766,9 @@ def ensure_initiated(api_function):
763766
"""Decorator to initiate only once in the first API call."""
764767

765768
def wrapper(*args, **kwargs):
766-
if _collection_download_manager is None:
767-
_read_content_manifests()
769+
with ENSURE_INITIATED_RLOCK:
770+
if _collection_download_manager is None:
771+
_read_content_manifests()
768772
return api_function(*args, **kwargs)
769773

770774
return wrapper

0 commit comments

Comments
 (0)