Skip to content

Commit

Permalink
Add new exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
alfred82santa committed May 17, 2017
1 parent f348722 commit c0d0eb9
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 8 deletions.
5 changes: 4 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,14 @@ v0.6.1
- Pool plugin now add ``blocked_by_pool`` attribute to session containing elapsed time (seconds) on pool. It allows
to log this time using log plugins.

- Pool plugin now add ``blocked_by_ratelimit`` attribute to session containing elapsed time (seconds) blocked by
- RateLimit plugin now add ``blocked_by_ratelimit`` attribute to session containing elapsed time (seconds) blocked by
rate limit. It allows to log this time using log plugins.

- Tests improved.

- Added new exceptions: :class:`~service_client.plugins.TooManyRequestsPendingError` and
:class:`~service_client.plugins.TooMuchTimePendingError`.

- Added decorator in order to help to build service clients. It allows to define a method using a request model
but to call it using keywords to build request model which will be used to call method.

Expand Down
21 changes: 19 additions & 2 deletions service_client/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,20 @@ class RequestLimitError(Exception):
pass


class TooManyRequestsPendingError(RequestLimitError):
pass


class TooMuchTimePendingError(RequestLimitError):
pass


class BaseLimitPlugin(BasePlugin):
SESSION_ATTR_TIME_BLOCKED = 'blocked'

TOO_MANY_REQ_PENDING_MSG = "Too many requests pending"
TOO_MUCH_TIME_MSG = "Request blocked too much time"

def __init__(self, limit=1, timeout=None, hard_limit=None):
self.limit = limit
self._counter = 0
Expand All @@ -342,7 +353,7 @@ async def _acquire(self):
break

if self._hard_limit is not None and self._hard_limit < self.pending:
raise RequestLimitError("Too many requests pending")
raise TooManyRequestsPendingError(self.TOO_MANY_REQ_PENDING_MSG)

if self._fut is None:
self._fut = self.service_client.loop.create_future()
Expand All @@ -356,7 +367,7 @@ async def _acquire(self):
if timeout <= 0:
raise TimeoutError()
except TimeoutError:
raise RequestLimitError("Request blocked too much time")
raise TooMuchTimePendingError(self.TOO_MUCH_TIME_MSG)
finally:
self._pending -= 1

Expand All @@ -383,6 +394,9 @@ def close(self):
class Pool(BaseLimitPlugin):
SESSION_ATTR_TIME_BLOCKED = 'blocked_by_pool'

TOO_MANY_REQ_PENDING_MSG = "Too many requests pending on pool"
TOO_MUCH_TIME_MSG = "Request blocked too much time on pool"

async def on_response(self, endpoint_desc, session, request_params, response):
self._release()

Expand All @@ -394,6 +408,9 @@ async def on_exception(self, endpoint_desc, session, request_params, ex):
class RateLimit(BaseLimitPlugin):
SESSION_ATTR_TIME_BLOCKED = 'blocked_by_ratelimit'

TOO_MANY_REQ_PENDING_MSG = "Too many requests pending by rate limit"
TOO_MUCH_TIME_MSG = "Request blocked too much time by rate limit"

def __init__(self, period=1, *args, **kwargs):
super(RateLimit, self).__init__(*args, **kwargs)
self.period = period
Expand Down
1 change: 1 addition & 0 deletions service_client/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def random_token(length=10):


class ObjectWrapper:

def __init__(self, obj):
self.__dict__['_obj'] = None
self.__dict__['_data'] = {}
Expand Down
10 changes: 5 additions & 5 deletions tests/tests_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from service_client import ConnectionClosedError
from service_client.plugins import PathTokens, Timeout, Headers, QueryParams, Elapsed, InnerLogger, OuterLogger, \
TrackingToken, Pool, RequestLimitError, RateLimit
TrackingToken, Pool, RateLimit, TooMuchTimePendingError, TooManyRequestsPendingError
from service_client.utils import ObjectWrapper


Expand Down Expand Up @@ -1022,7 +1022,7 @@ async def test_timeout(self):
await self.plugin.before_request(self.endpoint_desc, self.session,
self.request_params)

with self.assertRaisesRegex(RequestLimitError, "Request blocked too much time"):
with self.assertRaisesRegex(TooMuchTimePendingError, "Request blocked too much time on pool"):
await self.plugin.before_request(self.endpoint_desc, self.session,
self.request_params)

Expand All @@ -1037,7 +1037,7 @@ async def test_hard_limit(self):
asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session,
self.request_params))

with self.assertRaisesRegex(RequestLimitError, "Too many requests pending"):
with self.assertRaisesRegex(TooManyRequestsPendingError, "Too many requests pending on pool"):
await asyncio.wait_for(self.plugin.before_request(self.endpoint_desc, self.session,
self.request_params), timeout=1)

Expand Down Expand Up @@ -1160,7 +1160,7 @@ async def test_timeout(self):
await self.plugin.before_request(self.endpoint_desc, self.session,
self.request_params)

with self.assertRaisesRegex(RequestLimitError, "Request blocked too much time"):
with self.assertRaisesRegex(TooMuchTimePendingError, "Request blocked too much time by rate limit"):
await self.plugin.before_request(self.endpoint_desc, self.session,
self.request_params)

Expand All @@ -1175,7 +1175,7 @@ async def test_hard_limit(self):
asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session,
self.request_params))

with self.assertRaisesRegex(RequestLimitError, "Too many requests pending"):
with self.assertRaisesRegex(TooManyRequestsPendingError, "Too many requests pending by rate limit"):
await asyncio.wait_for(self.plugin.before_request(self.endpoint_desc, self.session,
self.request_params), timeout=1)

Expand Down

0 comments on commit c0d0eb9

Please sign in to comment.