Skip to content

Producer callback is unable to utilise python raise to propagate errors #184

@Samreay

Description

@Samreay

To reproduce:

  1. Start a pulsar standalone instance, via
docker run -it -p 6650:6650 -p 8080:8080 --tmpfs /pulsar/data apachepulsar/pulsar:3.1.0 bin/pulsar standalone
  1. Paste the following code into a file:
import time

import pulsar


def callback(result: pulsar.Result, message_id: pulsar.MessageId):
    if result == pulsar.Result.Timeout:
        raise ValueError()


client = pulsar.Client("pulsar://localhost:6650")
producer = client.create_producer("topic-example", send_timeout_millis=1)
producer.send_async(b"hello", callback)
time.sleep(1)
  1. Run the code. You should see something akin to:
...
2023-12-27 14:23:19.550 INFO  [139722145527360] ProducerImpl:209 | [persistent://public/default/topic-example, ] Created producer on broker [127.0.0.1:56868 -> 127.0.0.1:6650] 
terminate called after throwing an instance of 'pybind11::error_already_set'
  what():  ValueError: <EMPTY MESSAGE>

At:
  /home/sam/arenko/service-utils/tmp.py(8): callback

[1]    53944 IOT instruction  /home/sam/arenko/service-utils/.venv/bin/python 

Something about pybind and the C++ code means that errors cannot be raised in the callback function, which is obviously an issue for propagating errors up the python callstack. This might be because the callback function exists independently of the async event loop that it should be using, and so there's nowhere for the error to go. A try, except clause around everything won't work either, because the terminate there is a forceful termination, the entire app is dead in an instant.

Expected behaviour: The callback function acts as a standard python function with normal exception handling.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions