Skip to content

Commit 6d3690a

Browse files
fix: ensure bytes cannot go negative on requests sent to the server (#300)
This can happen if the server sends a message that goes over the byte limit, which should never happen, but apparently does in edge cases. This ensures that the client doesn't fail if this happens. fixes: #294
1 parent f2dc815 commit 6d3690a

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

google/cloud/pubsublite/internal/wire/flow_control_batcher.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
_MAX_INT64 = 0x7FFFFFFFFFFFFFFF
2121

2222

23+
def _clamp(val: int):
24+
if val > _MAX_INT64:
25+
return _MAX_INT64
26+
if val < 0:
27+
return 0
28+
return val
29+
30+
2331
class _AggregateRequest:
2432
_request: FlowControlRequest.meta.pb
2533

@@ -39,10 +47,13 @@ def __add__(self, other: FlowControlRequest):
3947
return self
4048

4149
def to_optional(self) -> Optional[FlowControlRequest]:
42-
if self._request.allowed_messages == 0 and self._request.allowed_bytes == 0:
50+
allowed_messages = _clamp(self._request.allowed_messages)
51+
allowed_bytes = _clamp(self._request.allowed_bytes)
52+
if allowed_messages == 0 and allowed_bytes == 0:
4353
return None
4454
request = FlowControlRequest()
45-
request._pb = self._request
55+
request._pb.allowed_messages = allowed_messages
56+
request._pb.allowed_bytes = allowed_bytes
4657
return request
4758

4859

tests/unit/pubsublite/internal/wire/flow_control_batcher_test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,17 @@ def test_add_remove():
4242
restart_2 = batcher.request_for_restart()
4343
assert restart_2.allowed_bytes == 5
4444
assert restart_2.allowed_messages == 1
45+
46+
47+
def test_negative_bytes_not_negative_request():
48+
batcher = FlowControlBatcher()
49+
batcher.add(FlowControlRequest(allowed_bytes=10, allowed_messages=3))
50+
restart_1 = batcher.request_for_restart()
51+
assert restart_1.allowed_bytes == 10
52+
assert restart_1.allowed_messages == 3
53+
batcher.on_messages(
54+
[SequencedMessage(size_bytes=10000), SequencedMessage(size_bytes=3)]
55+
)
56+
restart_2 = batcher.request_for_restart()
57+
assert restart_2.allowed_bytes == 0
58+
assert restart_2.allowed_messages == 1

0 commit comments

Comments
 (0)