question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Technical Question]How do I handle azure.iot.device send_message hanging when message quota is exhausted

See original GitHub issue

I have a project on raspberry pi that sends telemetry data to azure hub. An issue I am coming up against is when I have exceeded by daily quota of messages being sent from my device to cloud, the following line hangs.

await client.send_message(message)

I am trying to get over this by using asyncio.wait_for, and setting a timeout of 2 secs, so that my code will not wait indefinitely to return from the send_message() method.

My code does timeout after the specified time, but I get another error that Im not sure how to deal with.

The code Im using is below…

from azure.iot.device.aio import IoTHubDeviceClient
from azure.iot.device import Message
import time
import asyncio
from datetime import datetime

    
async def SendMessage(clientPairingId,clientDeviceId,type,subType,deviceState,pairingSetpoint=None):

        

    messageTemplate = """{{"iotDeviceId":"{iotDeviceId}","timeStampUTC":"{timeStampUTC}","clientPairingId":"{clientPairingId}","clientDeviceId":"{clientDeviceId}","type":"{type}","subType":"{subType}","state": "{deviceState}","setPoint": "{pairingSetpoint}"}}"""        
    connectionString="**********"
    client = IoTHubDeviceClient.create_from_connection_string(connectionString)
    
    await client.connect()
    
    message = Message(messageTemplate.format(iotDeviceId="xx1",
                                            clientPairingId=clientPairingId,
                                            clientDeviceId=clientDeviceId,
                                            type=type,
                                            subType=subType,
                                            deviceState=deviceState,
                                            pairingSetpoint=pairingSetpoint,
                                            timeStampUTC=datetime.utcnow()))
   

    
    
    await client.send_message(message)
    #await asyncio.sleep(300)
    await client.shutdown()

async def main():
    for i in range(1):
        try:
            coros=[SendMessage(clientPairingId="cp1",clientDeviceId="cd1",type="D",subType="ST1",deviceState="On",pairingSetpoint="n/a")]
            
            await asyncio.wait_for(asyncio.gather(*coros),.5)
            
        except asyncio.TimeoutError:
            print("Timed out")
        except asyncio.CancelledError:
            print("Cancelled")
        except Exception as e:
            print(e)
        except:
            print("catch all")

def handle_exception(loop, context):
    msg=context.get("exception",context["message"])
    
if __name__ == "__main__":
    s = time.perf_counter()
    #asyncio.run(main())
    asyncio.run(main(),debug=False)
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")

output ################################################# Timed out _GatheringFuture exception was never retrieved future: <_GatheringFuture finished exception=ClientError(‘Unexpected failure’)> Traceback (most recent call last): File “/usr/local/lib/python3.7/dist-packages/azure/iot/device/iothub/aio/async_clients.py”, line 33, in handle_result return await callback.completion() File “/usr/local/lib/python3.7/dist-packages/azure/iot/device/common/async_adapter.py”, line 94, in completion return await self.future concurrent.futures._base.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File “/home/pi/CabinetFarming/WIP/POC_SimpleAzureSendMessageMock.py”, line 30, in SendMessage await client.send_message(message) File “/usr/local/lib/python3.7/dist-packages/azure/iot/device/aio/patch_documentation.py”, line 60, in send_message return await super(IoTHubDeviceClient_, self).send_message(message) File “/usr/local/lib/python3.7/dist-packages/azure/iot/device/iothub/aio/async_clients.py”, line 301, in send_message await handle_result(callback) File “/usr/local/lib/python3.7/dist-packages/azure/iot/device/iothub/aio/async_clients.py”, line 53, in handle_result raise exceptions.ClientError(message=“Unexpected failure”, cause=e) azure.iot.device.exceptions.ClientError: ClientError(‘Unexpected failure’) caused by CancelledError() POC_SimpleAzureSendMessageMock.py executed in 0.51 seconds.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:34 (13 by maintainers)

github_iconTop GitHub Comments

1reaction
terryhollandcommented, Jun 23, 2021

I currently have some issue with my azure subscription and my services are disabled. I am trying to resolve asap after which I will be able to test. I will let you know as soon as I have done so

0reactions
terryhollandcommented, Jun 29, 2021

This may be because Im calling this code from multiple threads. I will try to lock the code and run again continuously. I need this code to run 24/7 so I will keep test going for as long as possible

Read more comments on GitHub >

github_iconTop Results From Across the Web

IoTHubQuota Exceeded - Microsoft Q&A
Once this happens, each attempt to send a message from any device, results in that device hanging. I need to handle this as...
Read more >
Understand Azure IoT Hub quotas and throttling
This article provides a description of the quotas that apply to IoT Hub and the expected throttling behavior.
Read more >
Azure IoT Device Client, How Much Buffered Data in day while ...
So if you send too many too fast, the RAM will be exhausted. But there is a timeout control for how long a...
Read more >
Troubleshooting Azure IoT Hub error codes | Microsoft Learn
When trying to send a cloud-to-device message, you may see that the request fails with the error 403004 or DeviceMaximumQueueDepthExceeded.
Read more >
Microsoft.Azure.Devices.Client.Exceptions Namespace
This exception is thrown when the IoT hub has been suspended. This is likely due to exceeding Azure spending limits. To resolve the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found