api_views: use loop to prevent NFS errors on GET (#41379)
File can disapear more frequently on NFS as open() is not atomic (NFS filehandle refers to an inode but they don't lock it like an open file descriptor).
This commit is contained in:
parent
9a2c6b23ed
commit
7b292a2c17
|
@ -21,8 +21,11 @@ try:
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
try:
|
||||||
|
from time import process_time
|
||||||
|
except ImportError:
|
||||||
|
from time import clock as process_time
|
||||||
|
|
||||||
from django.utils.six.moves.urllib import parse as urlparse
|
from django.utils.six.moves.urllib import parse as urlparse
|
||||||
|
|
||||||
|
@ -180,30 +183,32 @@ class PetalAPIView(APIView):
|
||||||
|
|
||||||
@logit
|
@logit
|
||||||
def get(self, request, partner_name, cut_uuid, petal_name):
|
def get(self, request, partner_name, cut_uuid, petal_name):
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
if_none_match = request.META.get('HTTP_IF_NONE_MATCH')
|
if_none_match = request.META.get('HTTP_IF_NONE_MATCH')
|
||||||
if_none_match = if_none_match and [x.strip() for x in if_none_match.split(',')]
|
if_none_match = if_none_match and [x.strip() for x in if_none_match.split(',')]
|
||||||
|
|
||||||
petal = self.get_petal(partner_name, cut_uuid, petal_name)
|
start = process_time()
|
||||||
if if_none_match:
|
while process_time() - start < 10:
|
||||||
if if_none_match == ['*'] or petal.etag in if_none_match:
|
petal = self.get_petal(partner_name, cut_uuid, petal_name)
|
||||||
return Response(
|
if if_none_match:
|
||||||
status=status.HTTP_304_NOT_MODIFIED,
|
if if_none_match == ['*'] or petal.etag in if_none_match:
|
||||||
headers={
|
return Response(
|
||||||
'ETag': petal.etag
|
status=status.HTTP_304_NOT_MODIFIED,
|
||||||
}
|
headers={
|
||||||
)
|
'ETag': petal.etag
|
||||||
# verify file exists before creating a StreamingHttpResponse
|
}
|
||||||
# as StreamingHttpResponse generate its content after the Django global try/catch
|
)
|
||||||
try:
|
# verify file exists before creating a StreamingHttpResponse
|
||||||
petal.data.open()
|
# as StreamingHttpResponse generate its content after the Django global try/catch
|
||||||
except IOError as e:
|
try:
|
||||||
logger.error('file not found "%s": %s', petal.data.path, e)
|
petal.data.open(mode='rb')
|
||||||
return HttpResponse('missing file', status=500)
|
response = HttpResponse(petal.data.read(), content_type=petal.content_type)
|
||||||
response = StreamingHttpResponse(
|
except IOError:
|
||||||
petal.data.chunks(),
|
continue
|
||||||
content_type=petal.content_type,
|
finally:
|
||||||
)
|
petal.data.close()
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return HttpResponse(status=500, reason='Too many updates')
|
||||||
response['ETag'] = petal.etag
|
response['ETag'] = petal.etag
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue