Azure / azure-event-hubs-c

C client library for Azure Event Hubs https://azure.microsoft.com/services/event-hubs
Other
7 stars 18 forks source link

100% CPU Load calling EventHubClient_Send #6

Closed alepez closed 7 years ago

alepez commented 7 years ago

I'm using EventHubClient with Linux on x86_64 and after the first call to EventHubClient_Send, the program is using 100% of cpu.

Events are successfully sent.

To test it:

#include <azure_c_shared_utility/platform.h>

#include <eventdata.h>
#include <eventhubclient.h>

#include <iostream>
#include <unistd.h>
#include <vector>

int main() {
  platform_init();
  const char* connectionString = "_PLACE_HERE_YOUR_CONNECTION_STRING_";
  const char* eventhubPath = "_PLACE_HERE_YOUR_PATH_";

  auto client = EventHubClient_CreateFromConnectionString(connectionString, eventhubPath);

  std::vector<unsigned char> data{{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}};
  EVENTDATA_HANDLE dataHandle = EventData_CreateWithNewMemory(data.data(), data.size());

  while (true) {
    if (EventHubClient_Send(client, dataHandle) != EVENTHUBCLIENT_OK) {
      std::cerr << "cannot send event :(\n";
    } else {
      std::cerr << "event sent :)\n";
    }

    ::sleep(1);
  }

  EventHubClient_Destroy(client);
  platform_deinit();
}

Compile with GCC 4.9.4:

g++ example.cpp -o example -std=c++11 -leventhub_client -luamqp -laziotsharedutil -lssl -lcrypto -lpthread

I investigated with valgrind/callgrind, finding out EventhubClientThread is using the cpu.

Adding a sleep in EventhubClientThread loop keeps the cpu idle:

File: eventhubclient.c


static int EventhubClientThread(void* userContextCallback)
{
    EVENTHUBCLIENT_STRUCT* eventhubInfo = (EVENTHUBCLIENT_STRUCT*)userContextCallback;
    while (eventhubInfo->threadToContinue == THREAD_CONTINUE)
    {
        if (Lock(eventhubInfo->lockInfo) == LOCK_OK)
        {
            EventHubClient_LL_DoWork(eventhubInfo->eventhubclientLLHandle);
            (void)Unlock(eventhubInfo->lockInfo);
        }
        else
        {
            LOG_ERROR(EVENTHUBCLIENT_ERROR);
        }
        usleep(1000);
    }
    return 0;
}

I guess this isn't the right solution.

dcristoloveanu commented 7 years ago

Hi @alepez

I am picking up doing some maintenance on this repo. Firstly, I would say sorry for the delay, but it probably does not matter anymore - it has been so long.

There clearly should be a ThreadAPI_Sleep in EventhubClientThread. I will file a PR and merge that fix.

Additionally at some point the IOs used by the EH SDK (and by IoTHub SDK) from azure-c-shared-utility will receive a select-like API that will allow not having sleeps, but actually waiting for readable/writable.

Thanks, /Dan

dcristoloveanu commented 7 years ago

The change of having a 1 ms sleep has been commit to master, thus closing this.

Thanks, /Dan