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.

thread safe Producer/Consumer/AdminClient Dispose methods

See original GitHub issue

Calling Dispose on a Producer, Consumer or AdminClient whilst an instance method that makes use of the librdkafka handle is executing on another thread is not supported and may result in an access violation exception. Doing this is an anti-pattern, but we should provide better behavior if the user does do this (probably block Dispose until outstanding methods complete).

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
mhowlettcommented, Dec 11, 2019

our documentation really needs improving yes. the tradeoffs are do you get transactions (for example) or better docs? you’re getting the former, but perhaps it should be the latter. we’ll get there. the only other place you need to be careful (that I can recall) is the log handler, since it can be called on any arbitrary librdkafka thread.

0reactions
pgrmcommented, Dec 17, 2019

@mhowlett sry in case I mixed up the terminology, yes my background tasks store the offset, the commit is done by keeping EnableAutoCommit on true

the background threads are actually slightly more sophisticated, I just didn’t want to get into it, as I thought that the issue most likely lies in the Dispose method, but just a quick recap - the records are processed by an Rx.Net-observable pipeline, guaranteed in order. There is one pipeline / subscribed topic + partition. The pipeline is basically equivalent to:

new Subject<ConsumeResult<string, string>>()
    .TakeWhile(_ => consumer.IsActive) // stop processing the pipeline when we can't store the offset anyway
    .Select(x => Observable.Create<ConsumeResult<string, string>>(async o =>
    {
        try
        {
            await consumeItemAsync(x);
            o.OnNext(x);
            o.OnCompleted();
        }
        catch (Exception ex)
        {
            o.OnError(ex);
        }
    }))
    // that whole thing above together with this concat guarantees synchronous in order processing
    .Concat()
    .TakeWhile(_ => consumer.IsActive) // double check if it wasn't disposed in the meanwhile
    .Do(consumer.StoreOffset) // the consumer has the locking implemented and should double check once more in case it wasn't really disposed in the meanwhile

and this part seems to work really smoothly.

We actually only have that problem in one service, maybe it’s because it’s handling the most messages, but maybe it’s because in this service handling a message can take quite a long time. Because the service is delivering messages to external parties, and their average response time is in the 10s of seconds, we have many concurrent pipelines active as waiting for an HTTP response doesn’t consume the thread from the pool.

Just trying to give you all the info I have - in case there is some weird edge case I don’t know about

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is the correct way to dispose of a producer thread ...
1 Answer 1 ... I think you are working at too low a level. If there is only one producer and consumer, you...
Read more >
Spring Cloud Stream Kafka Binder Reference Guide
Since the consumer is not thread-safe, you must call these methods on the calling thread. The following simple application shows how to pause...
Read more >
Pulsar Java client
All the methods in producer, consumer, reader and TableView of a Java client are thread-safe. Javadoc for the Pulsar client is divided into...
Read more >
Azure Service Bus client library for .NET
Thread safety. We guarantee that all client instance methods are thread-safe and independent of each other (guideline).
Read more >
c# - Lockfree customer producer problem
Multiple threads may Store processes, and another thread will dispose it (but only single thread will dispose at time). This is effectively ...
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