Skip to content

Telemetry messages are double-counted against the message rate limit #96

@joshafield

Description

@joshafield

Description

When sending telemetry data, each message incorrectly consumes two tokens from the message rate limit bucket instead of the expected one. This causes the client to hit the message rate limit twice as fast as expected.

Steps to Reproduce

import logging
import time
from tb_device_mqtt import TBDeviceMqttClient
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
TB_SERVER = "localhost"
TB_ACCESS_TOKEN = "TEST_TOKEN"
TEST_RATE_LIMIT_STR = "5:60"

def run_test():
    client = TBDeviceMqttClient(host=TB_SERVER, username=TB_ACCESS_TOKEN, telemetry_rate_limit=TEST_RATE_LIMIT_STR)
    client._TBDeviceMqttClient__is_connected = True #mock connected state
    for i in range(1, 4):
        print(f"\n>>> Sending message {i}...")
        start_time = time.monotonic()
        client.send_telemetry({"message_count": i})
        end_time = time.monotonic()

        duration = end_time - start_time
        print(f"send_telemetry() call took {duration:.4f} seconds.")
        if i < 3:
            if duration > 0.1:
                print("!!! UNEXPECTED: A fast message took longer than 0.1s.")
        else:  # This is the crucial third message
            if duration < 0.1:
                print("!!! TEST FAILED: The 3rd message was fast, but it should have blocked.")
                print("This would indicate tokens are only consumed once.")
            else:
                print(">>> BUG CONFIRMED: The 3rd message was slow, as expected.")
                print("This proves the bucket (5 tokens) was exhausted by two 2-token messages.")
    client.stop()


if __name__ == "__main__":
    run_test()

Root Cause

msg_rate_limit.increase_rate_limit_counter() is called from two different stages of the send_telemetry call stack.

  1. In _send_request() L1066
  2. In __send_split_message L1143

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions