Skip to content

Commit

Permalink
refactor: separating client GET and POST timeout values (StellarCN#315)
Browse files Browse the repository at this point in the history
- Using shorter default timeout for GET requests.
- Using Horizon submit transaction timeout with grace for POST requests.
  • Loading branch information
bantalon authored May 11, 2020
1 parent 3216e50 commit bfc31a2
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ venv.bak/

# mypy
.mypy_cache/

# IDE
.idea/
12 changes: 7 additions & 5 deletions stellar_sdk/client/aiohttp_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
import aiohttp
from aiohttp_sse_client.client import EventSource

from . import defines
from .base_async_client import BaseAsyncClient
from .response import Response
from ..__version__ import __version__

logger = logging.getLogger(__name__)

# four ledgers sec, let's retry faster and not wait 60 secs.
DEFAULT_REQUEST_TIMEOUT = 20
DEFAULT_NUM_RETRIES = 3
DEFAULT_BACKOFF_FACTOR = 0.5
USER_AGENT = "py-stellar-sdk/%s/AiohttpClient" % __version__
Expand All @@ -30,21 +29,24 @@ class AiohttpClient(BaseAsyncClient):
which represents the interface for making requests to a server instance.
:param pool_size: persistent connection to Horizon and connection pool
:param request_timeout: the timeout for all requests
:param request_timeout: the timeout for all GET requests
:param post_timeout: the timeout for all POST requests
:param backoff_factor: a backoff factor to apply between attempts after the second try
:param user_agent: the server can use it to identify you
"""

def __init__(
self,
pool_size: Optional[int] = None,
request_timeout: float = DEFAULT_REQUEST_TIMEOUT,
request_timeout: float = defines.DEFAULT_GET_TIMEOUT_SECONDS,
post_timeout: float = defines.DEFAULT_POST_TIMEOUT_SECONDS,
backoff_factor: Optional[float] = DEFAULT_BACKOFF_FACTOR,
user_agent: Optional[str] = None,
**kwargs
) -> None:
self.backoff_factor: Optional[float] = backoff_factor
self.request_timeout: float = request_timeout
self.post_timeout: float = post_timeout

# init session
if pool_size is None:
Expand Down Expand Up @@ -99,7 +101,7 @@ async def post(self, url: str, data: Dict[str, str] = None) -> Response:
:raise: :exc:`ConnectionError <stellar_sdk.exceptions.ConnectionError>`
"""
try:
response = await self._session.post(url, data=data)
response = await self._session.post(url, data=data, timeout=aiohttp.ClientTimeout(total=self.post_timeout))
return Response(
status_code=response.status,
text=await response.text(),
Expand Down
7 changes: 7 additions & 0 deletions stellar_sdk/client/defines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Two ledgers average time + 1 sec
DEFAULT_GET_TIMEOUT_SECONDS = 11

# https://github.com/stellar/go/blob/7c4596db1ad107f770bd6e5a694ea5129440cb1e/services/horizon/internal/txsub/system.go#L314
_HORIZON_SUBMIT_TRANSACTION_API_TIMEOUT_SECONDS = 30
# POST is only used for submitting transactions to Horizon. Therefore we take the Horizon value with some grace.
DEFAULT_POST_TIMEOUT_SECONDS = _HORIZON_SUBMIT_TRANSACTION_API_TIMEOUT_SECONDS * 1.1
12 changes: 7 additions & 5 deletions stellar_sdk/client/requests_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
from urllib3.exceptions import NewConnectionError
from urllib3.util import Retry

from . import defines
from ..__version__ import __version__
from ..client.base_sync_client import BaseSyncClient
from ..client.response import Response
from ..exceptions import ConnectionError

# four ledgers sec, let's retry faster and not wait 60 secs.
DEFAULT_REQUEST_TIMEOUT = 20
DEFAULT_NUM_RETRIES = 3
DEFAULT_BACKOFF_FACTOR = 0.5
USER_AGENT = "py-stellar-sdk/%s/RequestsClient" % __version__
Expand All @@ -32,7 +31,8 @@ class RequestsClient(BaseSyncClient):
:param pool_size: persistent connection to Horizon and connection pool
:param num_retries: configurable request retry functionality
:param request_timeout: the timeout for all requests
:param request_timeout: the timeout for all GET requests
:param post_timeout: the timeout for all POST requests
:param backoff_factor: a backoff factor to apply between attempts after the second try
:param session: the request session
:param stream_session: the stream request session
Expand All @@ -42,14 +42,16 @@ def __init__(
self,
pool_size: int = DEFAULT_POOLSIZE,
num_retries: int = DEFAULT_NUM_RETRIES,
request_timeout: int = DEFAULT_REQUEST_TIMEOUT,
request_timeout: int = defines.DEFAULT_GET_TIMEOUT_SECONDS,
post_timeout: float = defines.DEFAULT_POST_TIMEOUT_SECONDS,
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
session: Session = None,
stream_session: Session = None,
):
self.pool_size: int = pool_size
self.num_retries: int = num_retries
self.request_timeout: int = request_timeout
self.post_timeout: float = post_timeout
self.backoff_factor: float = backoff_factor

# adding 504 to the tuple of statuses to retry
Expand Down Expand Up @@ -134,7 +136,7 @@ def post(self, url: str, data: Dict[str, str] = None) -> Response:
:raise: :exc:`ConnectionError <stellar_sdk.exceptions.ConnectionError>`
"""
try:
resp = self._session.post(url, data=data, timeout=self.request_timeout)
resp = self._session.post(url, data=data, timeout=self.post_timeout)
except (RequestException, NewConnectionError) as err:
raise ConnectionError(err)
return Response(
Expand Down

0 comments on commit bfc31a2

Please sign in to comment.