thingsboard-python-client-sdk icon indicating copy to clipboard operation
thingsboard-python-client-sdk copied to clipboard

Telemetry messages are double-counted against the message rate limit

Open joshafield opened this issue 9 months ago • 0 comments

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

joshafield avatar Jun 26 '25 15:06 joshafield