Hi,
I'm having reliability issues with the IoT Hub. I wrote a very simple application that sends ten messages per second to an S2 Hub (which should be able to handle 70 messages per second). The timeout on messages is set to 2 seconds. Sending 500 messages, and getting about 44 errors: {'InvalidStateError': 37, 'ConnectionDroppedError': 3, 'Connection reset by peer': 4, 'Timeout': 37}. Is there something wrong with the code, or is this expected behavior based on the current level of service?
import asyncio
import sys
from azure.iot.device.aio import IoTHubDeviceClient
# IoTHubDeviceClient reports errors to stderr. Using this class to grab and count them before printing
class Redirect_stderr:
stderr = sys.stderr
errors_to_grab = {
"InvalidStateError": 0,
"ConnectionDroppedError": 0,
"Connection reset by peer": 0,
"Timeout": 0,
}
collect_errors = ""
def __enter__(self):
sys.stderr = self
def __exit__(self, exc_type, exc_val, exc_tb):
sys.stderr = self.stderr
print(self.collect_errors, file=sys.stderr)
sys.stderr.flush()
print(self.errors_to_grab)
def write(self, text):
for error in self.errors_to_grab.keys():
if error in text:
self.errors_to_grab[error] += 1
self.collect_errors += text
MIN_DELAY_BETWEEN_MESSAGES = 0.1
MESSAGE_TIMEOUT = 2
N_MESSAGES = 500
async def main():
with Redirect_stderr():
conn_str = "HostName=IoTHubForTest23.azure-devices.net;DeviceId=testDevice;SharedAccessKey=***redacted***"
client = IoTHubDeviceClient.create_from_connection_string(conn_str)
await client.connect()
for i in range(N_MESSAGES):
try:
print(f"message count: {i}")
task = asyncio.create_task(client.send_message(f"Message {i}"))
await asyncio.sleep(MIN_DELAY_BETWEEN_MESSAGES) # IoT Hub B1 has a message limit of four per second
await asyncio.wait_for(task, MESSAGE_TIMEOUT - MIN_DELAY_BETWEEN_MESSAGES)
except asyncio.TimeoutError:
print("Timeout", file=sys.stderr)
if __name__ == "__main__":
asyncio.run(main())