0

I have a Pulsar topic to which I am publishing messages through multiple producers. These producers are just goroutines and I am using SendAsync method on a producer to send messages but I keep getting Got unexpected send receipt for message warning. I looked into the client's library code (golang client for Pulsar) and found that this warning can show up only when the producer is not registered as a listener in this map map[uint64]ConnectionListener. But, how am I able to publish when the producer is not registered as a listener?

func benchmarkConcurrentProducers(b *testing.B, pool []pulsar.Producer, concur int, payload []byte) {
    wg := &sync.WaitGroup{}
    wg.Add(concur)

    for i := 0; i < concur; i++ {
        go Produce(pool[i], payload, wg)
    }
    wg.Wait()
}

func BenchmarkProducer(b *testing.B) {
    type config struct {
        Pulsarcfg struct {
            Url string `required: "true"`
        }
    }
    cfg := &config{}
    err := configor.Load(cfg, "../config.yml")
    require.Nil(b, err)

    client, err := pulsar.NewClient(pulsar.ClientOptions{
        URL:               cfg.Pulsarcfg.Url,
        OperationTimeout:  30 * time.Second,
        ConnectionTimeout: 30 * time.Second,
    })
    require.Nil(b, err)
    defer client.Close()

    concur := 4

    producerPool := make([]pulsar.Producer, concur)

    for i := 0; i < concur; i++ {
        p, err := New(client, string(i))
        require.Nil(b, err)
        defer p.Close()

        producerPool[i] = p
    }

    path, err := filepath.Abs("../events.json")
    if err != nil {
        log.Fatalf("invalid payload file path, %v", err)
    }
    f, err := ioutil.ReadFile(path)
    if err != nil {
        log.Fatalf("bad payload: %v", err)
    }

    b.Run("benchmark producer", func(b *testing.B) {
        // run the producer b.N times
        for n := 0; n < b.N; n++ {
            benchmarkConcurrentProducers(b, producerPool, concur, f)
        }
    })
}
Deepak Sah
  • 313
  • 1
  • 3
  • 14

2 Answers2

1

There can be two reasons for a producer to be not registered as a listener in map[uint64]ConnectionListener. Either, the producer was never created or the producer got closed. In my case, I was able to publish messages that means the producer was indeed created but since I was using SendAsync method to send messages it didn't block to receive the acknowledgement. And, I was using defer to close a producer after producing all the messages(I did use a wait group to make sure all the messages are sent before closing the producer) but producer got closed before receiving the acknowledgement and hence, the warning.

Deepak Sah
  • 313
  • 1
  • 3
  • 14
  • Can you post the code example? As you already said earlier, the connection listener map is tracked by the producer Id. Can you trace the producer Id in the log? – Ming L. May 11 '20 at 14:13
  • 1
    @MingL. I have added the code and yes I was able to see the producer Id in the logs. – Deepak Sah May 12 '20 at 07:15
0

I had the exact same error message. In my case I created a reader and a producer using the same client. Although the reader was already closed when I was producing new messages, I kept receiving this warning, and even worse, it would hang on the call to producer.Send(). I solved this by using separate clients for reading and for producing.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Paulo Quintans
  • 101
  • 1
  • 4