Skip to content

Commit

Permalink
obj: improve exceptions handling
Browse files Browse the repository at this point in the history
Still a bit crappy.
  • Loading branch information
fvennetier committed Mar 29, 2018
1 parent 8d4e102 commit 029a1d8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 36 deletions.
44 changes: 13 additions & 31 deletions oioswift/proxy/controllers/obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@

from oio.common import exceptions
from oio.common.http import ranges_from_http_header
from oio.common.green import SourceReadTimeout
from urllib3.exceptions import ReadTimeoutError

from oioswift.utils import check_if_none_match, handle_service_busy, \
handle_not_allowed, ServiceBusy
from oio.common.green import SourceReadTimeout
from oioswift.utils import check_if_none_match, \
handle_not_allowed, handle_oio_timeout, handle_service_busy

SLO = 'x-static-large-object'

Expand Down Expand Up @@ -120,19 +119,19 @@ class ObjectController(BaseObjectController):
@public
@cors_validation
@delay_denial
@handle_service_busy
def HEAD(self, req):
"""Handle HEAD requests."""
return self.GETorHEAD(req)

@public
@cors_validation
@delay_denial
@handle_service_busy
def GET(self, req):
"""Handle GET requests."""
return self.GETorHEAD(req)

@handle_oio_timeout
@handle_service_busy
@check_if_none_match
def GETorHEAD(self, req):
"""Handle HTTP GET or HEAD requests."""
Expand Down Expand Up @@ -243,6 +242,7 @@ def load_object_metadata(self, headers):
@cors_validation
@delay_denial
@handle_not_allowed
@handle_oio_timeout
@handle_service_busy
@check_if_none_match
def POST(self, req):
Expand Down Expand Up @@ -285,6 +285,7 @@ def _post_object(self, req, headers, stgpol):
@cors_validation
@delay_denial
@handle_not_allowed
@handle_oio_timeout
@handle_service_busy
@check_if_none_match
def PUT(self, req):
Expand Down Expand Up @@ -408,11 +409,6 @@ def _link_object(self, req):
raise HTTPConflict(request=req)
except exceptions.PreconditionFailed:
raise HTTPPreconditionFailed(request=req)
except SourceReadTimeout as err:
self.app.logger.warning(
_('ERROR Client read timeout (%ss)'), err.seconds)
self.app.logger.increment('client_timeouts')
raise HTTPRequestTimeout(request=req)
except exceptions.SourceReadError:
req.client_disconnect = True
self.app.logger.warning(
Expand All @@ -421,20 +417,12 @@ def _link_object(self, req):
raise HTTPClientDisconnect(request=req)
except exceptions.EtagMismatch:
return HTTPUnprocessableEntity(request=req)
except exceptions.OioTimeout:
self.app.logger.exception(
_('ERROR Timeout while uploading data or metadata'))
raise ServiceBusy()
except ServiceBusy:
except (exceptions.ServiceBusy, exceptions.OioTimeout):
raise
except ReadTimeoutError:
self.app.logger.exception(
_('ERROR Exception causing client disconnect'))
raise ServiceBusy()
except exceptions.ClientException as err:
# 481 = CODE_POLICY_NOT_SATISFIABLE
if err.status == 481:
raise ServiceBusy
raise exceptions.ServiceBusy()
self.app.logger.exception(
_('ERROR Exception transferring data %s'),
{'path': req.path})
Expand Down Expand Up @@ -485,6 +473,7 @@ def _store_object(self, req, data_source, headers):
raise HTTPConflict(request=req)
except exceptions.PreconditionFailed:
raise HTTPPreconditionFailed(request=req)
# FIXME(FVE): SourceReadTimeout should never be raised from oio!
except SourceReadTimeout as err:
self.app.logger.warning(
_('ERROR Client read timeout (%ss)'), err.seconds)
Expand All @@ -498,20 +487,12 @@ def _store_object(self, req, data_source, headers):
raise HTTPClientDisconnect(request=req)
except exceptions.EtagMismatch:
return HTTPUnprocessableEntity(request=req)
except exceptions.OioTimeout:
self.app.logger.exception(
_('ERROR Timeout while uploading data or metadata'))
raise ServiceBusy()
except ServiceBusy:
except (exceptions.ServiceBusy, exceptions.OioTimeout):
raise
except ReadTimeoutError:
self.app.logger.exception(
_('ERROR Exception causing client disconnect'))
raise ServiceBusy()
except exceptions.ClientException as err:
# 481 = CODE_POLICY_NOT_SATISFIABLE
if err.status == 481:
raise ServiceBusy
raise exceptions.ServiceBusy()
self.app.logger.exception(
_('ERROR Exception transferring data %s'),
{'path': req.path})
Expand Down Expand Up @@ -557,6 +538,7 @@ def _update_x_timestamp(self, req):
@cors_validation
@delay_denial
@handle_not_allowed
@handle_oio_timeout
@handle_service_busy
def DELETE(self, req):
"""HTTP DELETE request handler."""
Expand Down
3 changes: 2 additions & 1 deletion oioswift/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ def _oio_timeout_wrapper(self, req, *args, **kwargs):
headers = dict()
# TODO(FVE): choose the value according to the timeout
headers['Retry-After'] = '1'
return HTTPServiceUnavailable(request=req, body=str(exc))
return HTTPServiceUnavailable(request=req, headers=headers,
body=str(exc))
return _oio_timeout_wrapper


Expand Down
8 changes: 4 additions & 4 deletions tests/unit/controllers/test_obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ def read(self, size):
with patch('oio.api.replication.io.http_connect',
new=fake_http_connect):
resp = req.get_response(self.app)
self.assertEqual(resp.status_int, 499)
self.assertEqual(499, resp.status_int)

def test_PUT_chunkreadtimeout_during_data_transfer(self):
"""The gateway times out while reading from the client."""
Expand All @@ -286,7 +286,7 @@ def read(self, size):
with patch('oio.api.replication.io.http_connect',
new=fake_http_connect):
resp = req.get_response(self.app)
self.assertEqual(resp.status_int, 408)
self.assertEqual(408, resp.status_int)

def test_PUT_timeout_during_data_transfer(self):
"""The gateway times out while upload data to the server."""
Expand All @@ -305,7 +305,7 @@ def read(self, size):
with patch('oio.api.replication.io.http_connect',
new=fake_http_connect):
resp = req.get_response(self.app)
self.assertEqual(resp.status_int, 503)
self.assertEqual(503, resp.status_int)

def test_PUT_truncated_input_empty(self):
"""The gateway does not receive data from the client."""
Expand All @@ -324,7 +324,7 @@ def read(self, size):
with patch('oio.api.replication.io.http_connect',
new=fake_http_connect):
resp = req.get_response(self.app)
self.assertEqual(resp.status_int, 499)
self.assertEqual(499, resp.status_int)

def test_PUT_truncated_input_almost(self):
"""The gateway does not receive enough data from the client."""
Expand Down

0 comments on commit 029a1d8

Please sign in to comment.