1

According to documentation all non-static calls of EventHubClient are not thread-safe. This means that I cannot easily call the following function from wherever I want:

    public async Task SendBatchAsync(IList<EventData> eventHubBatch)
    {
        try
        {
            await this.eventHubClient.SendBatchAsync(eventHubBatch);
        }
        catch (Exception ex)
        {
            Console.WriteLine("ERROR (EH WRITER): {0}", ex.Message);
        }
    }

Wonder what are the alternatives?

  1. Locking
  2. Sync thread context
  3. Save to some queue and have one threadpool-based async/await while loop which reads from a queue and posts further to EventHub

UPDATE: Eric from Event Hub team confirmed that it is safe to use SendAsync in multithreaded environment as is.

UPDATE 2: MSDN documentation just got updated (within 2 hours, wow!). Now it says: "Any public static or instance members of this type are thread safe.".

ZakiMa
  • 5,637
  • 1
  • 24
  • 48
  • 1
    Arguable duplicate of http://stackoverflow.com/questions/26898930/what-azure-net-sdk-eventhubclient-instance-methods-are-threadsafe (or the answer http://stackoverflow.com/a/26920160/1012240 should work for you) – cacsar Apr 07 '16 at 07:15

2 Answers2

4

Cesar has provided the stackoverflow link that is fine as an answer. To supplement the info for your specific (EventHub) question:

  1. If you are asking "Will my data be corrupted if multiple threads call the API using the same instance" then answer is no, we do guarantee thread safety for data corruption scenario.

  2. If you are asking "Will my data ordering be preserved if multiple threads call the API using the same instance" then answer is depends, since we do preserve order as we receive data, but having multiple threads call the same instance means you cannot really be sure which call comes to our network implementation layer first. If you want ordering, send them as a single batch (SendBatchAsync) since we do guarantee order in a batch. Note that a single batch has a size limit though (256k in total)

The documentation link that you provided (https://msdn.microsoft.com/library/azure/microsoft.servicebus.messaging.eventhubclient.aspx) has incomplete/incorrect information and we will go back and review/edit as needed.

  • The wording of your answer makes it looks like you are making a comment not an answer, you should make the main point the fact that the API is thread safe then add the question of where did he see it as a secondary point. Also [things like "Thanks -Eric" is frowned upon, signatures are what your namecard is for and should not go in your post](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts). – Scott Chamberlain Apr 04 '16 at 23:18
  • Zaki has provided the documentation link: https://msdn.microsoft.com/library/azure/microsoft.servicebus.messaging.eventhubclient.aspx (specifically the Thread Safety section). So edit response as needed. – Hiu-Ming Eric Lam - MSFT Apr 13 '16 at 17:40
  • Thank you Eric for confirmation! – ZakiMa Apr 13 '16 at 17:59
0

According to MSDN EventHubClient documentation SendBatchAsync method is not guaranteed to be thread safe.

That being said, from my experience having quite a few workers using EventHubClient in multi-threaded manner, i never had any issue with thread safety using that specific method.

Regarding the options for handling this situation, it's no different than using any multi-threaded code which requires synchronization.

You can use any of the alternatives you suggested, in addition you can also create new EventHubClient per thread and therefor since only one thread uses it, you don't have the problem of mutual exclusion. I don't know about your scenario, this solution for example wouldn't be very good for system where you spawn many threads which uses EventHubClient and then get shut down (event hub connection time + allocation problems etc..)

Kobynet
  • 983
  • 11
  • 23