Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/aws-durable-execution-sdk-python-insight/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,12 @@ OTelExporter(endpoint="https://otlp.vendor.com/v1/logs", headers={"x-api-key": "

`POST` (or `method="PUT"`) the record as JSON to `url` with
`Content-Type: application/json` plus `headers`; a non-2xx status raises.
`timeout_ms` defaults to 10000. No IAM.
`timeout_ms` defaults to 10000 and currently applies to each socket operation
(the connect, each write of the request, and each read of the status line,
headers, and a non-2xx error body; a 2xx body is never read) rather than to the
whole request, so an endpoint that consumes or responds slowly can hold the
export open longer than `timeout_ms`; a future release may enforce it as a
whole-request deadline. No IAM.

```python
HttpExporter(url="https://hooks.example.com/insight", headers={"Authorization": "Bearer ..."})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ def http_send(
message. Redirects are not followed: a 3xx is returned like any other
failure. ``error_text`` is the first ``_MAX_ERROR_BODY_BYTES`` of a non-2xx
response body and empty on success; a success body is never read. Network
errors and timeouts propagate.
errors and timeouts propagate. ``timeout`` is ``urllib``'s per-socket-
operation timeout: it bounds the connect, each write of the request, and
each read of the status line, headers, and any error body separately, not
the request as a whole. A peer that keeps consuming or sending bytes
slowly can outlive it.
"""
request = urllib.request.Request(url, data=body, method=method)
for key, value in headers.items():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,17 @@ class HttpExporter:
"""Sends each record as a JSON body to any HTTP endpoint.

The endpoint must answer 2xx; any other status raises. ``timeout_ms``
bounds the whole request (default 10 seconds). ``max_record_size_bytes``
has no default because a generic endpoint has no known limit.
(default 10 seconds) is currently applied to each blocking socket
operation, not to the request as a whole: the connect, each write while
sending the request (headers and the record body), and each read of the
status line and headers, plus of the error body on a non-2xx response. A
successful response body is never read. An endpoint that stops reading or
goes silent fails at ``timeout_ms``, but one that keeps consuming or
sending bytes slowly can hold the request open for longer. A future
Comment thread
wangyb-A marked this conversation as resolved.
release may enforce ``timeout_ms`` as a deadline for the whole request, so
do not rely on a request being allowed to exceed it. Size the function
timeout with this in mind. ``max_record_size_bytes`` has no default because
a generic endpoint has no known limit.
"""

def __init__(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def test_non_2xx_response_raises(http_capture: HttpCapture) -> None:
exporter.export(_record())


def test_timeout_is_enforced(http_capture: HttpCapture) -> None:
def test_timeout_applies_to_a_silent_peer(http_capture: HttpCapture) -> None:
http_capture.delay_seconds = 1.0
exporter = HttpExporter(url=http_capture.url, timeout_ms=100)
with pytest.raises(TimeoutError):
Expand Down