Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C][Linux][AMQP] Send a message from a message call back #26

Closed
tameraw opened this issue Jan 12, 2017 · 24 comments
Closed

[C][Linux][AMQP] Send a message from a message call back #26

tameraw opened this issue Jan 12, 2017 · 24 comments
Assignees
Labels

Comments

@tameraw
Copy link
Contributor

tameraw commented Jan 12, 2017

From @lmussier on June 21, 2016 15:15

Hi,

I'm trying to send a message from a message received callback.
The use case it to sent a message upon message reception.

But it seems that I can't use IoTHubClient_SendEventAsync from within the message callback set via IoTHubClient_SetMessageCallback, I'm experiencing a dead lock when IoTHubClient_SendEventAsync try to lock the instance lock.

/* Codes_SRS_IOTHUBCLIENT_01_025: [IoTHubClient_SendEventAsync shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
        if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)

The solution on my side would be to create a queue where I'll put messages to send, but this is more or less what is it done in the SDK.
Is the impossibility to use IoTHubClient_SendEventAsync from within message reception call back a wished behavior ?

Copied from original issue: Azure/azure-iot-sdks#646

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @chrit-msft on June 22, 2016 18:7

@lmussier I just wanted to let you know we are investigating this and while I am trying to reproduce this issue internally can you confirm that you are using MQTT as the protocol here?

@tameraw tameraw self-assigned this Jan 12, 2017
@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @lmussier on June 23, 2016 7:51

@chrit-msft
Hi, I'm using AMQP.

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @chrit-msft on June 24, 2016 13:23

@lmussier I am unable to reproduce the behavior you are describing. Do you have any sample code I could look at?

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @lmussier on June 24, 2016 13:33

@chrit-msft sure, this is the content of my message receive callback.

[...]

//Made to be portable across time_t differences
    int epochSize = snprintf(NULL, 0, "%f", difftime(now, 0));
    //Add room for '\0'
    epochSize += 1;
    //Create buffer
    char payload[epochSize];
    //Convert
    snprintf(payload, (size_t) epochSize, "%f", difftime(now, 0));

    IOTHUB_MESSAGE_HANDLE iotMsg;

    iotMsg = IoTHubMessage_CreateFromByteArray((unsigned char*) payload, (size_t) epochSize);

    if (iotMsg != NULL) {

      IoTHubMessage_SetCorrelationId(iotMsg, p_incomingMessageID);

      IoTHubClient_SendEventAsync(g_iotHubClientHandle, iotMsg, NULL, NULL);
      IoTHubMessage_Destroy(iotMsg);
[...]

I just spoted the call to destroy right after the send could it be he problem ?
I've test without the destroy in the callback and get the same behaviour, IoTHubClient_SendEventAsync never return. (I'm using develop by the way : Info: IoT Hub SDK for C, version 1.0.8).

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @lmussier on June 27, 2016 8:29

@chrit-msft
Here is the sample code modified to show the issue
This is a modified version of iothub_client_sample_amqp.

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <stdio.h>
#include <stdlib.h>

#include "azure_c_shared_utility/platform.h"
#include "azure_c_shared_utility/threadapi.h"
#include "azure_c_shared_utility/crt_abstractions.h"
#include "iothub_client.h"
#include "iothub_message.h"
#include "iothubtransportamqp.h"

#ifdef MBED_BUILD_TIMESTAMP
#include "certs.h"
#endif // MBED_BUILD_TIMESTAMP

static const char* connectionString = "";
static int callbackCounter;

IOTHUB_CLIENT_HANDLE iotHubClientHandle = NULL;

DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_CONFIRMATION_RESULT, IOTHUB_CLIENT_CONFIRMATION_RESULT_VALUES);

typedef struct EVENT_INSTANCE_TAG
{
    IOTHUB_MESSAGE_HANDLE messageHandle;
    int messageTrackingId;  // For tracking the messages within the user callback.
} EVENT_INSTANCE;

static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
{
    const unsigned char* buffer = NULL;
    size_t size = 0;

    const char* messageId;
    // AMQP message properties
    if ((messageId = IoTHubMessage_GetMessageId(message)) == NULL)
    {
        messageId = "<null>";
    }

    if (userContextCallback == NULL)
    {
        (void)printf("Failed getting the context of the message received.\r\n");
    }
    else
    {
        int* counter = (int*)userContextCallback;


        IOTHUBMESSAGE_CONTENT_TYPE contentType = IoTHubMessage_GetContentType(message);

        if (contentType == IOTHUBMESSAGE_BYTEARRAY)
        {
            if (IoTHubMessage_GetByteArray(message, &buffer, &size) == IOTHUB_MESSAGE_OK)
            {
                (void)printf("Received Message [%d] with BINARY Data: <<<%.*s>>> & Size=%d\r\n", *counter, (int)size, buffer, (int)size);
            }
            else
            {
                (void)printf("Failed getting the BINARY body of the message received.\r\n");
            }
        }
        else if (contentType == IOTHUBMESSAGE_STRING)
        {
            if ((buffer = IoTHubMessage_GetString(message)) != NULL && (size = strlen(buffer)) > 0)
            {
                (void)printf("Received Message [%d] with STRING Data: <<<%.*s>>> & Size=%d\r\n", *counter, (int)size, buffer, (int)size);
            }
            else
            {
                (void)printf("Failed getting the STRING body of the message received.\r\n");
            }
        }
        else
        {
            (void)printf("Failed getting the body of the message received (type %i).\r\n", contentType);
        }

        (*counter)++;
    }

    // Retrieve properties from the message
    MAP_HANDLE mapProperties = IoTHubMessage_Properties(message);
    if (mapProperties != NULL)
    {
        const char*const* keys;
        const char*const* values;
        size_t propertyCount = 0;
        if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
        {
            if (propertyCount > 0)
            {
                size_t index;

                printf("Message Properties:\r\n");
                for (index = 0; index < propertyCount; index++)
                {
                    printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
                }
                printf("\r\n");
            }
        }
    }

    /* Some device specific action code goes here... */
    /* Send a message back */

    time_t now = time(NULL);
    int epochSize = snprintf(NULL, 0, "%f", difftime(now, 0));
    //Add room for '\0'
    epochSize += 1;
    //Create buffer
    char payload[epochSize];
    //Convert
    snprintf(payload, (size_t) epochSize, "%f", difftime(now, 0));

    IOTHUB_MESSAGE_HANDLE iotMsg;

    iotMsg = IoTHubMessage_CreateFromByteArray((unsigned char*) payload, (size_t) epochSize);
    IoTHubMessage_SetCorrelationId(iotMsg, messageId);

    (void)printf("Sending response message\n");

    IoTHubClient_SendEventAsync(iotHubClientHandle, iotMsg, NULL, NULL);

    (void)printf("Message on is way back\n");

    IoTHubMessage_Destroy(iotMsg);

    return IOTHUBMESSAGE_ACCEPTED;
}

static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
{
    EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
    (void)printf("Confirmation[%d] received for message tracking id = %d with result = %s\r\n", callbackCounter, eventInstance->messageTrackingId, ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
    /* Some device specific action code goes here... */
    callbackCounter++;
    IoTHubMessage_Destroy(eventInstance->messageHandle);
}

static char msgText[1024];
static char propText[1024];
#define MESSAGE_COUNT 5

void iothub_client_sample_amqp_run(void)
{


    EVENT_INSTANCE messages[MESSAGE_COUNT];

    srand((unsigned int)time(NULL));
    double avgWindSpeed = 10.0;

    callbackCounter = 0;
    int receiveContext = 0;

    (void)printf("Starting the IoTHub client sample AMQP over WebSockets...\r\n");

    if (platform_init() != 0)
    {
        (void)printf("ERROR: failed initializing the platform.\r\n");
    }
    else if ((iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, AMQP_Protocol)) == NULL)
    {
        (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
        platform_deinit();
    }
    else
    {
#ifdef MBED_BUILD_TIMESTAMP
        // For mbed add the certificate information
        if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
        {
            printf("failure to set option \"TrustedCerts\"\r\n");
        }
#endif // MBED_BUILD_TIMESTAMP

        /* Setting Message call back, so we can receive Commands. */
        if (IoTHubClient_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
        {
            (void)printf("ERROR: IoTHubClient_SetMessageCallback..........FAILED!\r\n");
        }
        else
        {
            (void)printf("IoTHubClient_SetMessageCallback...successful.\r\n");

            /* Now that we are ready to receive commands, let's send some messages */
            for (size_t i = 0; i < MESSAGE_COUNT; i++)
            {
                sprintf_s(msgText, sizeof(msgText), "{\"deviceId\":\"myFirstDevice\",\"windSpeed\":%.2f}", avgWindSpeed+(rand()%4+2) );
                if ((messages[i].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
                {
                    (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
                }
                else
                {
                    messages[i].messageTrackingId = i;

                    MAP_HANDLE propMap = IoTHubMessage_Properties(messages[i].messageHandle);
                    sprintf_s(propText, sizeof(propText), "PropMsg_%d", i);
                    if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
                    {
                        (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
                    }

                    if (IoTHubClient_SendEventAsync(iotHubClientHandle, messages[i].messageHandle, SendConfirmationCallback, &messages[i]) != IOTHUB_CLIENT_OK)
                    {
                        (void)printf("ERROR: IoTHubClient_SendEventAsync..........FAILED!\r\n");
                    }
                    else
                    {
                        (void)printf("IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub.\r\n");
                    }
                }
            }

            /* Wait for Commands. */
            (void)printf("Press any key to exit the application. \r\n");
            (void)getchar();
        }

        IoTHubClient_Destroy(iotHubClientHandle);
        platform_deinit();
    }
}

int main(void)
{
    iothub_client_sample_amqp_run();
    return 0;
}

Here are the logs

Starting the IoTHub client sample AMQP over WebSockets...
Info: IoT Hub SDK for C, version 1.0.9
IoTHubClient_SetMessageCallback...successful.
IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub.
IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub.
IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub.
IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub.
IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub.
Press any key to exit the application. 
-> Header (AMQP 3.1.0.0)
<- Header (AMQP 3.1.0.0)
<- [SASL MECHANISMS]* {{EXTERNAL,MSSBCBS,ANONYMOUS,PLAIN}}
-> [SASL INIT]* {MSSBCBS}
<- [SASL OUTCOME]* {0,<57 65 6C 63 6F 6D 65 21>}
Properties:* {0,NULL,NULL,NULL,cbs}Application properties:* {[name:cnm-ih-dev.azure-devices.net/devices/ludo],[operation:put-token],[type:servicebus.windows.net:sastoken]}Body - amqp value:* SharedAccessSignature sr=cnm-ih-dev.azure-devices.net/devices/ludo&sig=X8NKZMYYE7Mp92VL3ZylAYszOdMT4RrGwJ70Oq3g3BA%3d&se=1467019288&skn=Info: Event sender state changed [0->1]
Info: Event sender state changed [1->2]
Application properties:* {[PropName:PropMsg_0]}Application properties:* {[PropName:PropMsg_1]}Application properties:* {[PropName:PropMsg_2]}Application properties:* {[PropName:PropMsg_3]}Application properties:* {[PropName:PropMsg_4]}Received Message [0] with BINARY Data: <<<tetet>>> & Size=5
Message Properties:
    Key: iothub-ack Value: full

Sending response message

I think you have all the keys now.

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @chrit-msft on June 28, 2016 18:49

@lmussier I was unable to reproduce this behavior using IoTHubClient_LL_SendEventAsync() which I notice you are not using. Could you please try this while I run your code and look into this?

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @lmussier on July 6, 2016 16:48

@chrit-msft
It is working with LL apis, with on solo handle

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <stdio.h>
#include <stdlib.h>

#include "azure_c_shared_utility/platform.h"
#include "azure_c_shared_utility/threadapi.h"
#include "azure_c_shared_utility/crt_abstractions.h"
#include "iothub_client_ll.h"
#include "iothub_message.h"
#include "iothubtransportamqp.h"

#ifdef MBED_BUILD_TIMESTAMP
#include "certs.h"
#endif // MBED_BUILD_TIMESTAMP

/*String containing Hostname, Device Id & Device Key in the format:                         */
/*  "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"                */
/*  "HostName=<host_name>;DeviceId=<device_id>;SharedAccessSignature=<device_sas_token>"    */
static const char* connectionString = "";

static int callbackCounter;
static bool g_continueRunning;
static char msgText[1024];
static char propText[1024];
#define MESSAGE_COUNT       5
#define DOWORK_LOOP_NUM     3
static IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle = NULL;


typedef struct EVENT_INSTANCE_TAG
{
    IOTHUB_MESSAGE_HANDLE messageHandle;
    int messageTrackingId;  // For tracking the messages within the user callback.
} EVENT_INSTANCE;

static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
{
    int* counter = (int*)userContextCallback;
    const unsigned char* buffer = NULL;
    size_t size = 0;
    const char* messageId;
    const char* correlationId;

    // AMQP message properties
    if ((messageId = IoTHubMessage_GetMessageId(message)) == NULL)
    {
        messageId = "<null>";
    }

    if ((correlationId = IoTHubMessage_GetCorrelationId(message)) == NULL)
    {
        correlationId = "<null>";
    }

    // AMQP message content.
    IOTHUBMESSAGE_CONTENT_TYPE contentType = IoTHubMessage_GetContentType(message);

    if (contentType == IOTHUBMESSAGE_BYTEARRAY)
    {
        if (IoTHubMessage_GetByteArray(message, &buffer, &size) == IOTHUB_MESSAGE_OK)
        {
            (void)printf("Received Message [%d] (message-id: %s, correlation-id: %s) with BINARY Data: <<<%.*s>>> & Size=%d\r\n", *counter, messageId, correlationId,(int)size, buffer, (int)size);
        }
        else
        {
            (void)printf("Failed getting the BINARY body of the message received.\r\n");
        }
    }
    else if (contentType == IOTHUBMESSAGE_STRING)
    {
        if ((buffer = IoTHubMessage_GetString(message)) != NULL && (size = strlen(buffer)) > 0)
        {
            (void)printf("Received Message [%d] (message-id: %s, correlation-id: %s) with STRING Data: <<<%.*s>>> & Size=%d\r\n", *counter, messageId, correlationId, (int)size, buffer, (int)size);

            // If we receive the work 'quit' then we stop running
        }
        else
        {
            (void)printf("Failed getting the STRING body of the message received.\r\n");
        }
    }
    else
    {
        (void)printf("Failed getting the body of the message received (type %i).\r\n", contentType);
    }

    // Retrieve properties from the message
    MAP_HANDLE mapProperties = IoTHubMessage_Properties(message);
    if (mapProperties != NULL)
    {
        const char*const* keys;
        const char*const* values;
        size_t propertyCount = 0;
        if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
        {
            if (propertyCount > 0)
            {
                size_t index;

                printf("Message Properties:\r\n");
                for (index = 0; index < propertyCount; index++)
                {
                    printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
                }
                printf("\r\n");
            }
        }
    }

    if (memcmp(buffer, "quit", size) == 0)
    {
        g_continueRunning = false;
    }

    /* Some device specific action code goes here... */
        /* Send a message back */

    time_t now = time(NULL);
    int epochSize = snprintf(NULL, 0, "%f", difftime(now, 0));
    //Add room for '\0'
    epochSize += 1;
    //Create buffer
    char payload[epochSize];
    //Convert
    snprintf(payload, (size_t) epochSize, "%f", difftime(now, 0));

    IOTHUB_MESSAGE_HANDLE iotMsg;

    iotMsg = IoTHubMessage_CreateFromByteArray((unsigned char*) payload, (size_t) epochSize);
    IoTHubMessage_SetCorrelationId(iotMsg, messageId);

    (void)printf("Sending response message\n");

    IoTHubClient_LL_SendEventAsync(iotHubClientHandle, iotMsg, NULL, NULL);

    (void)printf("Message on is way back\n");
    (*counter)++;
    return IOTHUBMESSAGE_ACCEPTED;
}

static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
{
    EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
    //(void)printf("Confirmation[%d] received for message tracking id = %d with result = %s\r\n", callbackCounter, eventInstance->messageTrackingId, ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
    /* Some device specific action code goes here... */
    callbackCounter++;
    IoTHubMessage_Destroy(eventInstance->messageHandle);
}

void iothub_client_sample_amqp_run(void)
{

    EVENT_INSTANCE messages[MESSAGE_COUNT];

    g_continueRunning = true;
    srand((unsigned int)time(NULL));
    double avgWindSpeed = 10.0;

    callbackCounter = 0;
    int receiveContext = 0;

    (void)printf("Starting the IoTHub client sample AMQP...\r\n");

    if (platform_init() != 0)
    {
        printf("Failed to initialize the platform.\r\n");
    }
    else
    {
        if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, AMQP_Protocol)) == NULL)
        {
            (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
        }
        else
        {
            bool traceOn = true;
            IoTHubClient_LL_SetOption(iotHubClientHandle, "logtrace", &traceOn);

#ifdef MBED_BUILD_TIMESTAMP
            // For mbed add the certificate information
            if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
            {
                printf("failure to set option \"TrustedCerts\"\r\n");
            }
#endif // MBED_BUILD_TIMESTAMP

            /* Setting Message call back, so we can receive Commands. */
            if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
            {
                (void)printf("ERROR: IoTHubClient_SetMessageCallback..........FAILED!\r\n");
            }
            else
            {
                (void)printf("IoTHubClient_SetMessageCallback...successful.\r\n");

                /* Now that we are ready to receive commands, let's send some messages */
                size_t iterator = 0;
                do
                {
                    if (iterator < MESSAGE_COUNT)
                    {
                        sprintf_s(msgText, sizeof(msgText), "{\"deviceId\":\"myFirstDevice\",\"windSpeed\":%.2f}", avgWindSpeed + (rand() % 4 + 2));
                        if ((messages[iterator].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
                        {
                            (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
                        }
                        else
                        {
                            messages[iterator].messageTrackingId = (int)iterator;

                            MAP_HANDLE propMap = IoTHubMessage_Properties(messages[iterator].messageHandle);
                            sprintf_s(propText, sizeof(propText), "PropMsg_%d", (int)iterator);
                            if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
                            {
                                (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
                            }

                            if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[iterator].messageHandle, SendConfirmationCallback, &messages[iterator]) != IOTHUB_CLIENT_OK)
                            {
                                (void)printf("ERROR: IoTHubClient_SendEventAsync..........FAILED!\r\n");
                            }
                            else
                            {
                                (void)printf("IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub.\r\n");
                            }
                        }
                    }
                    IoTHubClient_LL_DoWork(iotHubClientHandle);
                    ThreadAPI_Sleep(1);

                    iterator++;
                } while (g_continueRunning);

                (void)printf("iothub_client_sample_mqtt has gotten quit message, call DoWork %d more time to complete final sending...\r\n", DOWORK_LOOP_NUM);
                for (size_t index = 0; index < DOWORK_LOOP_NUM; index++)
                {
                    IoTHubClient_LL_DoWork(iotHubClientHandle);
                    ThreadAPI_Sleep(1);
                }
            }
            IoTHubClient_LL_Destroy(iotHubClientHandle);
        }
        platform_deinit();
    }
}

int main(void)
{
    iothub_client_sample_amqp_run();
    return 0;
}

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @chrit-msft on July 14, 2016 15:51

@lmussier just to provide an update, we are working with the code owners on what the side effects, if any, will be introduced from modifying how we handle locking in this code path. I will provide another update with our results.

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @lmussier on September 6, 2016 9:16

@chrit-msft Hi, any update on the subject ?

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

@lmussier - Currently not supported. Is this a blocking issue on your end?

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @lmussier on September 21, 2016 14:48

@tameraw In a way, yes it is blocking. We are not able to support request response pattern directly with the client library. Some one who use the convenience API (like we do) will have to create a dedicated thread and manage a message queue to send responses to incoming messages.

The simple use case, send a message to the device, and respond to this message becomes a complicated stuff for something that should be directly supported.

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

@lmussier - Apologies for the delay on this. It's still on our list to consider adding such support. Meanwhile, if you'd like to provide a PR for this, we'd be happy to review it and give you feedback.

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @lmussier on October 10, 2016 12:38

@tameraw Unfortunately we have decided to support the feature outside the SDK code. The queue is manage in our code, not in the SDK.

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @olivierbloch on October 27, 2016 15:23

On this issue...
we are introducing C2D direct Methods to IoT Hub, which I believe address what you need.
For now it is available only over MQTT in our preview repository: https://github.com/azure/azure-iot-sdks-preview, but we are working on bringing the feature to AMQP as well and expect to have this done in a few days from now.
You can see progress in the develop branch:
https://azure.microsoft.com/en-us/documentation/articles/iot-hub-devguide-direct-methods/
https://github.com/Azure/azure-iot-sdks-preview/commit/bc2cf548512f6d4ea0e7f51d524edc9a7bd9631e
https://github.com/Azure/azure-iot-sdks-preview/commit/97f33a7ff1465d181d4e15b4a0deda8ffc17f4a7

@tameraw
Copy link
Contributor Author

tameraw commented Jan 12, 2017

From @lmussier on October 28, 2016 8:21

Glad to hear that, thanks.

@anporumb anporumb added bug and removed enhancement labels Jan 12, 2017
@anporumb
Copy link
Contributor

The initial deadlock reported will be fixed by the end of this month. Thank you. I will close this issue once code is released

Best Regards,
Andrei Porumb

@anporumb anporumb assigned mhshami01 and unassigned tameraw Jan 13, 2017
@anporumb
Copy link
Contributor

Hello @lmussier,

We cannot deliver this by end of the month as anticipated. We are actively working on it and will update you on it when we have news.

Best Regards,
Andrei Porumb

@anporumb
Copy link
Contributor

Hello @lmussier,

We are still working on this. Still working = one person doing just this. We did not forget about it.

Best Regards,
Andrei Porumb

@N6UDP
Copy link
Member

N6UDP commented Feb 24, 2017

Is this the same deadlock I end up getting between IoTHubClient_UploadToBlobAsync and IoTHubClient_SendEventAsync?

@lmussier
Copy link

Hi @N6UDP,

Could you explain what is your issue ? We are currently building around upload2blob and we are not able to test an upload occurring during send/receive message.

Is it what you are trying (and not able) to do?

@anporumb
Copy link
Contributor

anporumb commented Mar 1, 2017

Hello all,

We've fixed this for C2D messages callback in a non-multiplexed environment.

Best Regards,
Andrei Porumb

@anporumb
Copy link
Contributor

anporumb commented Mar 1, 2017

@N6UDP ,

Could you please open another github issue with the deadlock between IoTHubClient_UploadToBlobAsync and IoTHubClient_SendEventAsync? A minimal repro would help very much. Thank you.

Best Regards,
Andrei Porumb

@lmussier
Copy link

lmussier commented Mar 1, 2017

Hi,

To test this we need to remove our workaround, which consists of a sending queue. But if @N6UDP bug is "real" (don't think I don't trust you ^^) we sill need our workaround.

@anporumb fell free to close once it's released I'll check @N6UDP bug for the new deadlock problem.

@N6UDP
Copy link
Member

N6UDP commented Mar 1, 2017

@anporumb done.. see #82

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants