Is there an example anywhere for handling backoff ...
# singer-tap-development
r
Is there an example anywhere for handling backoff with an
X-RateLimit-Reset
header?
r
I tried implementing this with
backoff.runtime
as you do here, but not seeing what I expect... The wait time calculated from the response looks correct, but the actual time the SDK is waiting is different for some reason. Is this to do with jitter? ```2023-10-06 225742,390 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 3 X-RateLimit-Reset: 1696629521 2023-10-06 225742,492 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.081825, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 200, "status": "succeeded"}} 2023-10-06 225742,492 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 2 X-RateLimit-Reset: 1696629521 2023-10-06 225742,593 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.082664, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 200, "status": "succeeded"}} 2023-10-06 225742,593 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 1 X-RateLimit-Reset: 1696629522 2023-10-06 225742,715 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.085323, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 200, "status": "succeeded"}} 2023-10-06 225742,715 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1696629523 2023-10-06 225742,786 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.05414, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 429, "status": "failed"}} 2023-10-06 225742,786 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1696629523 2023-10-06 225742,787 Reset: 1696629523.0 Now: 1696629462.787018 Wait: 60.212981939315796 2023-10-06 225742,787 Backing off _request(...) for 54.4s (singer_sdk.exceptions.RetriableAPIError: 429 Client Error: Too Many Requests for path: /api/v2/logs) 2023-10-06 225742,787 Backing off 54.4 seconds after 1 tries calling function <bound method RESTStream._request of <tap_auth0.streams.LogsStream object at 0x7fb5c1b8ec40>> with args (<PreparedRequest [GET]>, None) and kwargs {} 2023-10-06 225837,260 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.055833, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 429, "status": "failed"}} 2023-10-06 225837,260 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1696629523 2023-10-06 225837,261 Reset: 1696629523.0 Now: 1696629517.261093 Wait: 5.738907098770142 2023-10-06 225837,261 Backing off _request(...) for 1.0s (singer_sdk.exceptions.RetriableAPIError: 429 Client Error: Too Many Requests for path: /api/v2/logs) 2023-10-06 225837,261 Backing off 1.0 seconds after 2 tries calling function <bound method RESTStream._request of <tap_auth0.streams.LogsStream object at 0x7fb5c1b8ec40>> with args (<PreparedRequest [GET]>, None) and kwargs {} 2023-10-06 225838,287 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.055472, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 429, "status": "failed"}} 2023-10-06 225838,288 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1696629523 2023-10-06 225838,288 Reset: 1696629523.0 Now: 1696629518.288333 Wait: 4.711667060852051 2023-10-06 225838,288 Backing off _request(...) for 3.8s (singer_sdk.exceptions.RetriableAPIError: 429 Client Error: Too Many Requests for path: /api/v2/logs) 2023-10-06 225838,288 Backing off 3.8 seconds after 3 tries calling function <bound method RESTStream._request of <tap_auth0.streams.LogsStream object at 0x7fb5c1b8ec40>> with args (<PreparedRequest [GET]>, None) and kwargs {} 2023-10-06 225842,130 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.034968, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_…
e
r
I thought this might fix it
Copy code
def backoff_jitter(self, value):
        self.logger.info(f"Jitter: {value}")
        return value
but I get the same issue:
Copy code
2023-10-06 23:40:53,555 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.068145, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 429, "status": "failed"}}
2023-10-06 23:40:53,555 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1696632114
2023-10-06 23:40:53,555 Reset: 1696632114.0 Now: 1696632053.555651 Wait: 60.44434905052185
2023-10-06 23:40:53,555 Backing off _request(...) for 50.1s (singer_sdk.exceptions.RetriableAPIError: 429 Client Error: Too Many Requests for path: /api/v2/logs)
2023-10-06 23:40:53,555 Backing off 50.1 seconds after 1 tries calling function <bound method RESTStream._request of <tap_auth0.streams.LogsStream object at 0x7f3ddc34ec10>> with args (<PreparedRequest [GET]>, None) and kwargs {}
2023-10-06 23:41:43,760 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.027469, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 429, "status": "failed"}}
2023-10-06 23:41:43,761 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1696632114
2023-10-06 23:41:43,761 Reset: 1696632114.0 Now: 1696632103.761188 Wait: 10.23881196975708
2023-10-06 23:41:43,761 Backing off _request(...) for 2.5s (singer_sdk.exceptions.RetriableAPIError: 429 Client Error: Too Many Requests for path: /api/v2/logs)
2023-10-06 23:41:43,761 Backing off 2.5 seconds after 2 tries calling function <bound method RESTStream._request of <tap_auth0.streams.LogsStream object at 0x7f3ddc34ec10>> with args (<PreparedRequest [GET]>, None) and kwargs {}
2023-10-06 23:41:46,299 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.047897, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 429, "status": "failed"}}
2023-10-06 23:41:46,299 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1696632114
2023-10-06 23:41:46,299 Reset: 1696632114.0 Now: 1696632106.299446 Wait: 7.700553894042969
2023-10-06 23:41:46,299 Backing off _request(...) for 2.3s (singer_sdk.exceptions.RetriableAPIError: 429 Client Error: Too Many Requests for path: /api/v2/logs)
2023-10-06 23:41:46,299 Backing off 2.3 seconds after 3 tries calling function <bound method RESTStream._request of <tap_auth0.streams.LogsStream object at 0x7f3ddc34ec10>> with args (<PreparedRequest [GET]>, None) and kwargs {}
2023-10-06 23:41:48,656 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.053343, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 429, "status": "failed"}}
2023-10-06 23:41:48,656 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1696632114
2023-10-06 23:41:48,656 Reset: 1696632114.0 Now: 1696632108.656409 Wait: 5.343590974807739
2023-10-06 23:41:48,656 Backing off _request(...) for 1.4s (singer_sdk.exceptions.RetriableAPIError: 429 Client Error: Too Many Requests for path: /api/v2/logs)
2023-10-06 23:41:48,656 Backing off 1.4 seconds after 4 tries calling function <bound method RESTStream._request of <tap_auth0.streams.LogsStream object at 0x7f3ddc34ec10>> with args (<PreparedRequest [GET]>, None) and kwargs {}
2023-10-06 23:41:50,040 INFO METRIC: {"metric_type": "timer", "metric": "http_request_duration", "value": 0.027334, "tags": {"stream": "stream_auth0_logs", "endpoint": "/logs", "http_status_code": 429, "status": "failed"}}
2023-10-06 23:41:50,040 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1696632114
2023-10-06 23:41:50,040 Giving up _request(...) after 5 tries (singer_sdk.exceptions.RetriableAPIError: 429 Client Error: Too Many Requests for path: /api/v2/logs)
It's like
backoff_jitter
is not called?
Oh I think you figured it out 😁
r
Yeah that got things working, but ideally I'd like to fix it using
X-RateLimit-Reset
...
I don't see that log message I put in
backoff_jitter
, so I don't think it's being called, right?
Either way, the issue we were having is fixed - this was more a question out of curiosity. 🙂
@edgar_ramirez_mondragon Would you accept a PR to support
RateLimit
headers in the SDK, as per https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/ (or perhaps when the RFC is published)?
e
@Reuben (Matatika) Sure thing! Do you mind creating an issue? Otherwise I can do it later today.
r
Sure, thanks. 🙂