From: Kyle Fuller Date: Fri, 23 Sep 2022 21:56:15 +0000 (+0100) Subject: feat: retry on rate limited requests X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=22772aef17f1e7c77d5185a3b995eb9b09768995;p=znc-palaver.git feat: retry on rate limited requests --- diff --git a/palaver.cpp b/palaver.cpp index 520aaa5..8362eda 100644 --- a/palaver.cpp +++ b/palaver.cpp @@ -118,8 +118,9 @@ struct PLVHTTPRequest : PLVHTTPMessage { class RetryStrategy { public: bool ShouldRetryRequest(unsigned int status) { + bool isRateLimited = status == 429; bool is5xx = status >= 500 && status <= 600; - return is5xx; + return isRateLimited || is5xx; } unsigned int GetMaximumRetryAttempts() { diff --git a/test/test_palaver.py b/test/test_palaver.py index 9c2710f..827f0f3 100644 --- a/test/test_palaver.py +++ b/test/test_palaver.py @@ -271,6 +271,62 @@ async def test_receiving_notification_with_push_token(znc): assert connected.called +async def test_receiving_notification_with_retry_on_rate_limit(znc): + reader, writer = znc + + async def connected(reader, writer): + headers, body = await read_push_request(reader) + assert headers['Authorization'] == 'Bearer abcdefg' + assert json.loads(body.decode('utf-8')) == { + 'badge': 1, + 'message': 'Test notification', + 'sender': 'palaver', + 'network': 'b758eaab1a4611a310642a6e8419fbff' + } + + if not hasattr(connected, 'requests'): + connected.requests = 1 + writer.write(b'HTTP/1.1 429 Too Many Requests\r\n') + else: + connected.requests += 1 + writer.write(b'HTTP/1.1 204 No Content\r\n') + + writer.write(b'Connection: close\r\n') + writer.write(b'\r\n') + + await writer.drain() + writer.close() + + server = await asyncio.start_server(connected, host='127.0.0.1', port=8121) + await asyncio.sleep(0.2) + addr = server.sockets[0].getsockname() + url = f'http://{addr[0]}:{addr[1]}/push' + + writer.write(b'PALAVER IDENTIFY 9167e47b01598af7423e2ecd3d0a3ec4 611d3a30a3d666fc491cdea0d2e1dd6e b758eaab1a4611a310642a6e8419fbff\r\n') + await writer.drain() + + line = await reader.readline() + assert line == b'PALAVER REQ *\r\n' + + writer.write(b'PALAVER BEGIN 9167e47b01598af7423e2ecd3d0a3ec4 611d3a30a3d666fc491cdea0d2e1dd6e\r\n') + writer.write(f'PALAVER SET PUSH-ENDPOINT {url}\r\n'.encode('utf-8')) + writer.write(f'PALAVER SET PUSH-TOKEN abcdefg\r\n'.encode('utf-8')) + writer.write(b'PALAVER END\r\n') + await writer.drain() + + writer.write(b'PRIVMSG *palaver :test\r\n') + await writer.drain() + + line = await reader.readline() + assert line == b':*palaver!znc@znc.in PRIVMSG admin :Notification sent to 1 clients.\r\n' + + await asyncio.sleep(1.2) + server.close() + await server.wait_closed() + + assert connected.requests == 2 + + async def test_receiving_notification_with_retry_on_server_error(znc): reader, writer = znc