44 * distributed with this work for additional information
55 * regarding copyright ownership. The ASF licenses this file
66 * to you under the Apache License, Version 2.0 (the
7- * "License"); you may not use this file except in compliance
7+ * "License"); you may not use this file except
88 * with the License. You may obtain a copy of the License at
99 *
1010 * http://www.apache.org/licenses/LICENSE-2.0
1616 * specific language governing permissions and limitations
1717 * under the License.
1818 */
19+
1920#include " utils.h"
2021
2122#include < pulsar/Consumer.h>
23+ #include < pulsar/ConsumerConfiguration.h>
24+ #include < pulsar/Result.h>
2225#include < pybind11/functional.h>
2326#include < pybind11/pybind11.h>
2427#include < pybind11/stl.h>
28+ #include < memory>
2529
2630namespace py = pybind11;
2731
2832void Consumer_unsubscribe (Consumer& consumer) {
2933 waitForAsyncResult ([&consumer](ResultCallback callback) { consumer.unsubscribeAsync (callback); });
3034}
3135
36+ void Consumer_unsubscribeAsync (Consumer& consumer, ResultCallback callback) {
37+ consumer.unsubscribeAsync ([callback] (Result result) {
38+ py::gil_scoped_acquire acquire;
39+ callback (result);
40+ });
41+ }
42+
3243Message Consumer_receive (Consumer& consumer) {
3344 return waitForAsyncValue<Message>([&](ReceiveCallback callback) { consumer.receiveAsync (callback); });
3445}
@@ -48,6 +59,7 @@ Message Consumer_receive_timeout(Consumer& consumer, int timeoutMs) {
4859 return msg;
4960}
5061
62+ // TODO: implement async variant
5163Messages Consumer_batch_receive (Consumer& consumer) {
5264 Messages msgs;
5365 Result res;
@@ -56,41 +68,39 @@ Messages Consumer_batch_receive(Consumer& consumer) {
5668 return msgs;
5769}
5870
71+ void Consumer_batch_receive_async (Consumer& consumer, BatchReceiveCallback callback){
72+ consumer.batchReceiveAsync ([callback](pulsar::Result result, pulsar::Messages messages){
73+ py::gil_scoped_acquire acquire;
74+ callback (result, messages);
75+ });
76+ }
77+
5978void Consumer_acknowledge (Consumer& consumer, const Message& msg) {
6079 waitForAsyncResult ([&](ResultCallback callback) { consumer.acknowledgeAsync (msg, callback); });
6180}
6281
63- void Consumer_acknowledgeAsync (Consumer& consumer, const Message& msg, py::object callback) {
64- // Capture the callback by value to ensure it's safe to use in the async context
82+ void Consumer_acknowledgeAsync (Consumer& consumer, const Message& msg, py::object callback){
6583 auto py_callback = std::make_shared<py::object>(callback);
6684
67- // Call the Pulsar asynchronous acknowledge method
68- consumer.acknowledgeAsync (msg, [py_callback](pulsar::Result result) {
69- // Acquire the Python GIL before calling any Python code
85+ consumer.acknowledgeAsync (msg, [py_callback](pulsar::Result result){
7086 py::gil_scoped_acquire acquire;
71-
72- try {
73- if (result == pulsar::ResultOk) {
74- py::print (" result ok" );
75- // Call the Python callback with None if the acknowledgment was successful
76- (*py_callback)(pulsar::ResultOk, py::none ());
77- py::print (" callback called" );
78- } else {
79- py::print (" error" );
80- // Raise a Python exception for failure
81- PyErr_SetString (PyExc_Exception, " AcknowledgeAsync failed" );
82- (*py_callback)(pulsar::ResultOk, py::none ()); // Or pass some error object to indicate failure
83- }
84- } catch (const py::error_already_set& e) {
85- throw py::error_already_set ();
86- }
87+ (*py_callback)(result, py::none ());
8788 });
8889}
8990
9091void Consumer_acknowledge_message_id (Consumer& consumer, const MessageId& msgId) {
9192 waitForAsyncResult ([&](ResultCallback callback) { consumer.acknowledgeAsync (msgId, callback); });
9293}
9394
95+ void Consumer_acknowledge_message_id_Async (Consumer& consumer, const MessageId& msgId, py::object callback){
96+ auto py_callback = std::make_shared<py::object>(callback);
97+
98+ consumer.acknowledgeAsync (msgId, [py_callback](pulsar::Result result){
99+ py::gil_scoped_acquire acquire;
100+ (*py_callback)(result, py::none ());
101+ });
102+ }
103+
94104void Consumer_negative_acknowledge (Consumer& consumer, const Message& msg) {
95105 Py_BEGIN_ALLOW_THREADS consumer.negativeAcknowledge (msg);
96106 Py_END_ALLOW_THREADS
@@ -105,6 +115,16 @@ void Consumer_acknowledge_cumulative(Consumer& consumer, const Message& msg) {
105115 waitForAsyncResult ([&](ResultCallback callback) { consumer.acknowledgeCumulativeAsync (msg, callback); });
106116}
107117
118+ void Consumer_acknowledge_cumulativeAsync (Consumer& consumer, const Message& msg, py::object callback){
119+ auto py_callback = std::make_shared<py::object>(callback);
120+
121+ consumer.acknowledgeCumulativeAsync (msg, [py_callback](pulsar::Result result){
122+ py::gil_scoped_acquire acquire;
123+ (*py_callback)(result);
124+ });
125+ }
126+
127+ // TODO: implement async variant
108128void Consumer_acknowledge_cumulative_message_id (Consumer& consumer, const MessageId& msgId) {
109129 waitForAsyncResult (
110130 [&](ResultCallback callback) { consumer.acknowledgeCumulativeAsync (msgId, callback); });
@@ -123,10 +143,19 @@ void Consumer_pauseMessageListener(Consumer& consumer) { CHECK_RESULT(consumer.p
123143
124144void Consumer_resumeMessageListener (Consumer& consumer) { CHECK_RESULT (consumer.resumeMessageListener ()); }
125145
146+ // TODO: implement async variant
126147void Consumer_seek (Consumer& consumer, const MessageId& msgId) {
127148 waitForAsyncResult ([msgId, &consumer](ResultCallback callback) { consumer.seekAsync (msgId, callback); });
128149}
129150
151+ void Consumer_seekAsync (Consumer& consumer, const MessageId& msgId, ResultCallback callback){
152+ consumer.seekAsync (msgId, [callback](pulsar::Result result){
153+ py::gil_scoped_acquire acquire;
154+ callback (result);
155+ });
156+ }
157+
158+ // TODO: implement async variant
130159void Consumer_seek_timestamp (Consumer& consumer, uint64_t timestamp) {
131160 waitForAsyncResult (
132161 [timestamp, &consumer](ResultCallback callback) { consumer.seekAsync (timestamp, callback); });
@@ -152,15 +181,19 @@ void export_consumer(py::module_& m) {
152181 .def (" subscription_name" , &Consumer::getSubscriptionName, py::return_value_policy::copy)
153182 .def (" consumer_name" , &Consumer::getConsumerName, py::return_value_policy::copy)
154183 .def (" unsubscribe" , &Consumer_unsubscribe)
184+ .def (" unsubscribe_async" , &Consumer_unsubscribeAsync)
155185 .def (" receive" , &Consumer_receive)
156186 .def (" receive" , &Consumer_receive_timeout)
157187 .def (" receive_async" , &Consumer_receiveAsync)
158188 .def (" batch_receive" , &Consumer_batch_receive)
189+ .def (" batch_receive_async" , &Consumer_batch_receive_async)
159190 .def (" acknowledge" , &Consumer_acknowledge)
160191 .def (" acknowledge" , &Consumer_acknowledge_message_id)
161192 .def (" acknowledge_async" , &Consumer_acknowledgeAsync)
193+ .def (" acknowledge_async" , &Consumer_acknowledge_message_id_Async)
162194 .def (" acknowledge_cumulative" , &Consumer_acknowledge_cumulative)
163195 .def (" acknowledge_cumulative" , &Consumer_acknowledge_cumulative_message_id)
196+ .def (" acknowledge_cumulative_async" , &Consumer_acknowledge_cumulativeAsync)
164197 .def (" negative_acknowledge" , &Consumer_negative_acknowledge)
165198 .def (" negative_acknowledge" , &Consumer_negative_acknowledge_message_id)
166199 .def (" close" , &Consumer_close)
@@ -170,6 +203,7 @@ void export_consumer(py::module_& m) {
170203 .def (" redeliver_unacknowledged_messages" , &Consumer::redeliverUnacknowledgedMessages)
171204 .def (" seek" , &Consumer_seek)
172205 .def (" seek" , &Consumer_seek_timestamp)
206+ .def (" seek_async" , Consumer_seekAsync)
173207 .def (" is_connected" , &Consumer_is_connected)
174208 .def (" get_last_message_id" , &Consumer_get_last_message_id);
175209}
0 commit comments