Skip to content

Commit 4362aef

Browse files
authored
python sdk 5.0.2 (#900)
1、Fix the bug related to message ID length 2、Fix the bug which sync the subscription relationship without expression 3、The subscribe method adds raise exception 4、Set default values for AK and SK with empty strings
1 parent 7d55793 commit 4362aef

File tree

14 files changed

+143
-83
lines changed

14 files changed

+143
-83
lines changed

.github/workflows/python_build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
jobs:
55
flake8:
66
name: flake8
7-
runs-on: ubuntu-latest
7+
runs-on: ubuntu-22.04
88
steps:
99
- name: Checkout
1010
uses: actions/checkout@v3
@@ -17,7 +17,7 @@ jobs:
1717
run: |
1818
flake8 --ignore=E501,W503 --exclude python/rocketmq/grpc_protocol python
1919
isort:
20-
runs-on: ubuntu-latest
20+
runs-on: ubuntu-22.04
2121
steps:
2222
- name: Checkout
2323
uses: actions/checkout@v3
@@ -30,7 +30,7 @@ jobs:
3030
run: |
3131
isort --check --diff --skip python/rocketmq/grpc_protocol python
3232
black:
33-
runs-on: ubuntu-latest
33+
runs-on: ubuntu-22.04
3434
steps:
3535
- name: Checkout
3636
uses: actions/checkout@v3

python/example/async_producer_example.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,29 @@ def handle_send_result(result_future):
2525

2626

2727
if __name__ == '__main__':
28-
endpoints = "endpoints"
29-
credentials = Credentials("ak", "sk")
28+
endpoints = "foobar.com:8080"
29+
credentials = Credentials()
30+
# if auth enable
31+
# credentials = Credentials("ak", "sk")
3032
config = ClientConfiguration(endpoints, credentials)
3133
topic = "topic"
34+
producer = Producer(config, (topic,))
35+
3236
try:
33-
producer = Producer(config, (topic,))
3437
producer.startup()
35-
msg = Message()
36-
msg.topic = topic
37-
msg.body = "hello, rocketmq.".encode('utf-8')
38-
msg.tag = "rocketmq-send-message"
39-
msg.keys = "send_async"
40-
msg.add_property("send", "async")
41-
send_result_future = producer.send_async(msg)
42-
send_result_future.add_done_callback(handle_send_result)
38+
try:
39+
for i in range(10):
40+
msg = Message()
41+
msg.topic = topic
42+
msg.body = "hello, rocketmq.".encode('utf-8')
43+
msg.tag = "rocketmq-send-message"
44+
msg.keys = "send_async"
45+
msg.add_property("send", "async")
46+
send_result_future = producer.send_async(msg)
47+
send_result_future.add_done_callback(handle_send_result)
48+
except Exception as e:
49+
print(f"async producer{producer.__str__()} send message raise exception: {e}")
50+
producer.shutdown()
4351
except Exception as e:
44-
print(f"async producer example raise exception: {e}")
52+
print(f"{producer.__str__()} startup raise exception: {e}")
53+
producer.shutdown()

python/example/async_simple_consumer_example.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,40 @@
2121

2222
def receive_callback(receive_result_future, consumer):
2323
messages = receive_result_future.result()
24+
print(f"{consumer.__str__()} receive {len(messages)} messages.")
2425
for msg in messages:
25-
print(f"{consumer.__str__()} receive {len(messages)} messages in callback.")
2626
try:
2727
consumer.ack(msg)
28-
print(f"receive and ack message:{msg.message_id} in callback.")
28+
print(f"ack message:{msg.message_id}.")
2929
except Exception as exception:
30-
print(f"receive message callback raise exception: {exception}")
30+
print(f"receive message raise exception: {exception}")
3131

3232

3333
if __name__ == '__main__':
34-
endpoints = "endpoints"
35-
credentials = Credentials("ak", "sk")
34+
endpoints = "foobar.com:8080"
35+
credentials = Credentials()
36+
# if auth enable
37+
# credentials = Credentials("ak", "sk")
3638
config = ClientConfiguration(endpoints, credentials)
3739
topic = "topic"
40+
41+
simple_consumer = SimpleConsumer(config, "consumer-group")
3842
try:
39-
simple_consumer = SimpleConsumer(config, "consumer_group")
4043
simple_consumer.startup()
41-
simple_consumer.subscribe(topic)
42-
while True:
43-
time.sleep(5)
44-
future = simple_consumer.receive_async(32, 15)
45-
future.add_done_callback(functools.partial(receive_callback, consumer=simple_consumer))
44+
try:
45+
simple_consumer.subscribe(topic)
46+
# use tag filter
47+
# simple_consumer.subscribe(topic, FilterExpression("tag"))
48+
while True:
49+
try:
50+
time.sleep(1)
51+
future = simple_consumer.receive_async(32, 15)
52+
future.add_done_callback(functools.partial(receive_callback, consumer=simple_consumer))
53+
except Exception as e:
54+
print(f"{simple_consumer.__str__()} receive topic:{topic} raise exception: {e}")
55+
except Exception as e:
56+
print(f"{simple_consumer.__str__()} subscribe topic:{topic} raise exception: {e}")
57+
simple_consumer.shutdown()
4658
except Exception as e:
47-
print(f"simple consumer example raise exception: {e}")
59+
print(f"{simple_consumer.__str__()} startup raise exception: {e}")
60+
simple_consumer.shutdown()

python/example/normal_producer_example.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,30 @@
1616
from rocketmq import ClientConfiguration, Credentials, Message, Producer
1717

1818
if __name__ == '__main__':
19-
endpoints = "endpoints"
20-
credentials = Credentials("ak", "sk")
19+
endpoints = "foobar.com:8080"
20+
credentials = Credentials()
21+
# if auth enable
22+
# credentials = Credentials("ak", "sk")
2123
config = ClientConfiguration(endpoints, credentials)
2224
topic = "topic"
25+
producer = Producer(config, (topic,))
26+
2327
try:
24-
producer = Producer(config, (topic,))
2528
producer.startup()
26-
msg = Message()
27-
msg.topic = topic
28-
msg.body = "hello, rocketmq.".encode('utf-8')
29-
msg.tag = "rocketmq-send-message"
30-
msg.keys = "send_sync"
31-
msg.add_property("send", "sync")
32-
res = producer.send(msg)
33-
print(f"{producer.__str__()} send message success. {res}")
34-
producer.shutdown()
35-
print(f"{producer.__str__()} shutdown.")
29+
try:
30+
msg = Message()
31+
msg.topic = topic
32+
msg.body = "hello, rocketmq.".encode('utf-8')
33+
msg.tag = "rocketmq-send-message"
34+
msg.keys = "send_sync"
35+
msg.add_property("send", "sync")
36+
res = producer.send(msg)
37+
print(f"{producer.__str__()} send message success. {res}")
38+
producer.shutdown()
39+
print(f"{producer.__str__()} shutdown.")
40+
except Exception as e:
41+
print(f"normal producer example raise exception: {e}")
42+
producer.shutdown()
3643
except Exception as e:
37-
print(f"normal producer example raise exception: {e}")
44+
print(f"{producer.__str__()} startup raise exception: {e}")
45+
producer.shutdown()

python/example/simple_consumer_example.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,32 @@
1616
from rocketmq import ClientConfiguration, Credentials, SimpleConsumer
1717

1818
if __name__ == '__main__':
19-
endpoints = "endpoints"
20-
credentials = Credentials("ak", "sk")
19+
endpoints = "foobar.com:8080"
20+
credentials = Credentials()
21+
# if auth enable
22+
# credentials = Credentials("ak", "sk")
2123
config = ClientConfiguration(endpoints, credentials)
2224
topic = "topic"
25+
simple_consumer = SimpleConsumer(config, "consumer-group")
2326
try:
24-
simple_consumer = SimpleConsumer(config, "consumer-group")
2527
simple_consumer.startup()
26-
simple_consumer.subscribe(topic)
27-
while True:
28-
try:
29-
messages = simple_consumer.receive(32, 15)
30-
if messages is not None:
31-
print(f"{simple_consumer.__str__()} receive {len(messages)} messages.")
32-
for msg in messages:
33-
simple_consumer.ack(msg)
34-
print(f"{simple_consumer.__str__()} ack message:[{msg.message_id}].")
35-
except Exception as e:
36-
print(f"receive or ack message raise exception: {e}")
28+
try:
29+
simple_consumer.subscribe(topic)
30+
# use tag filter
31+
# simple_consumer.subscribe(topic, FilterExpression("tag"))
32+
while True:
33+
try:
34+
messages = simple_consumer.receive(32, 15)
35+
if messages is not None:
36+
print(f"{simple_consumer.__str__()} receive {len(messages)} messages.")
37+
for msg in messages:
38+
simple_consumer.ack(msg)
39+
print(f"{simple_consumer.__str__()} ack message:[{msg.message_id}].")
40+
except Exception as e:
41+
print(f"receive or ack message raise exception: {e}")
42+
except Exception as e:
43+
print(f"{simple_consumer.__str__()} subscribe topic:{topic} raise exception: {e}")
44+
simple_consumer.shutdown()
3745
except Exception as e:
38-
print(f"simple consumer example raise exception: {e}")
46+
print(f"{simple_consumer.__str__()} startup raise exception: {e}")
47+
simple_consumer.shutdown()

python/example/transaction_producer_example.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,20 @@ def check(self, message: Message) -> TransactionResolution:
2525

2626

2727
if __name__ == '__main__':
28-
endpoints = "endpoints"
29-
credentials = Credentials("ak", "sk")
28+
endpoints = "foobar.com:8080"
29+
credentials = Credentials()
30+
# if auth enable
31+
# credentials = Credentials("ak", "sk")
3032
config = ClientConfiguration(endpoints, credentials)
3133
topic = "topic"
34+
producer = Producer(config, (topic,))
35+
3236
try:
33-
producer = Producer(config, (topic,), TestChecker())
3437
producer.startup()
38+
except Exception as e:
39+
print(f"{producer.__str__()} startup raise exception: {e}")
40+
41+
try:
3542
transaction = producer.begin_transaction()
3643
msg = Message()
3744
msg.topic = topic
@@ -40,6 +47,6 @@ def check(self, message: Message) -> TransactionResolution:
4047
msg.keys = "send_transaction"
4148
msg.add_property("send", "transaction")
4249
res = producer.send(msg, transaction)
43-
print(f"{producer.__str__()} send half message. {res}")
50+
print(f"transaction producer{producer.__str__()} send half message success. {res}")
4451
except Exception as e:
45-
print(f"transaction producer example raise exception: {e}")
52+
print(f"transaction producer{producer.__str__()} example raise exception: {e}")

python/rocketmq/v5/client/client.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
class Client:
3636

37+
CALLBACK_THREADS_NUM = 5
38+
3739
def __init__(self, client_configuration, topics, client_type: ClientType, tls_enable=False):
3840
if client_configuration is None:
3941
raise IllegalArgumentException("clientConfiguration should not be null.")
@@ -57,7 +59,7 @@ def __init__(self, client_configuration, topics, client_type: ClientType, tls_en
5759
else:
5860
self.__topics = set()
5961
self.__callback_result_queue = Queue()
60-
self.__callback_result_thread = None
62+
self.__callback_threads = []
6163
self.__is_running = False
6264
self.__client_thread_task_enabled = False
6365
self.__had_shutdown = False
@@ -76,7 +78,7 @@ def startup(self):
7678
logger.warn(
7779
f"update topic exception when client startup, ignore it, try it again in scheduler. exception: {e}")
7880
self.__start_scheduler()
79-
self.__start_callback_handler()
81+
self.__start_async_rpc_callback_handler()
8082
self.__is_running = True
8183
self._start_success()
8284
except Exception as e:
@@ -240,12 +242,19 @@ def __schedule_clear_idle_rpc_channels(self):
240242

241243
""" callback handler for async method """
242244

243-
def __start_callback_handler(self):
245+
def __start_async_rpc_callback_handler(self):
244246
# a thread to handle callback when using async method such as send_async(), receive_async().
245247
# this handler switches user's callback thread from RpcClient's _io_loop_thread to client's callback_handler_thread
246-
self.__callback_result_thread = threading.Thread(name="callback_handler_thread", target=self.__handle_callback)
247-
self.__callback_result_thread.daemon = True
248-
self.__callback_result_thread.start()
248+
try:
249+
for i in range(Client.CALLBACK_THREADS_NUM):
250+
th = threading.Thread(name=f"callback_handler_thread-{i}", target=self.__handle_callback)
251+
th.daemon = True
252+
self.__callback_threads.append(th)
253+
th.start()
254+
logger.info(f"{self.__str__()} start async rpc callback thread:{th} success.")
255+
except Exception as e:
256+
print(f"{self.__str__()} start async rpc callback raise exception: {e}")
257+
raise e
249258

250259
def __handle_callback(self):
251260
while True:
@@ -263,7 +272,7 @@ def __handle_callback(self):
263272
self.__callback_result_queue.task_done()
264273
else:
265274
break
266-
logger.info(f"{self.__str__()} stop client callback result handler thread success.")
275+
logger.info(f"{self.__str__()} stop client callback result handler thread:{threading.current_thread()} success.")
267276

268277
""" protect """
269278

@@ -375,6 +384,7 @@ def __setting_write(self, endpoints):
375384
req = self._sync_setting_req(endpoints)
376385
callback = functools.partial(self.__setting_write_callback, endpoints=endpoints)
377386
future = self.__rpc_client.telemetry_write_async(endpoints, req)
387+
logger.debug(f"{self.__str__()} send setting to {endpoints.__str__()}, {req}")
378388
future.add_done_callback(callback)
379389

380390
def __retrieve_telemetry_stream_stream_call(self, endpoints, rebuild=False):
@@ -466,9 +476,11 @@ def __stop_client_threads(self):
466476
self.__clear_idle_rpc_channels_threading_event.set()
467477
self.__clear_idle_rpc_channels_scheduler.join()
468478

469-
if self.__callback_result_thread is not None:
479+
for i in range(Client.CALLBACK_THREADS_NUM):
470480
self._set_future_callback_result(CallbackResult.end_callback_thread_result())
471-
self.__callback_result_thread.join()
481+
482+
for i in range(Client.CALLBACK_THREADS_NUM):
483+
self.__callback_threads[i].join()
472484

473485
self.__topic_route_scheduler = None
474486
self.__topic_route_scheduler_threading_event = None
@@ -478,7 +490,8 @@ def __stop_client_threads(self):
478490
self.__sync_setting_scheduler_threading_event = None
479491
self.__clear_idle_rpc_channels_scheduler = None
480492
self.__clear_idle_rpc_channels_threading_event = None
481-
self.__callback_result_thread = None
493+
self.__callback_result_queue = None
494+
self.__callback_threads = None
482495

483496
""" property """
484497

python/rocketmq/v5/client/client_configuration.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222

2323
class Credentials:
2424

25-
def __init__(self, ak, sk):
26-
self.__ak = ak
27-
self.__sk = sk
25+
def __init__(self, ak="", sk=""):
26+
self.__ak = ak if ak is not None else ""
27+
self.__sk = sk if sk is not None else ""
2828

2929
@property
3030
def ak(self):

python/rocketmq/v5/consumer/simple_consumer.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def subscribe(self, topic, filter_expression: FilterExpression = None):
7272
self.__subscriptions.put(topic, filter_expression if filter_expression is not None else FilterExpression())
7373
except Exception as e:
7474
logger.error(f"subscribe exception: {e}")
75+
raise e
7576

7677
def unsubscribe(self, topic):
7778
if self.is_running is False:
@@ -141,14 +142,15 @@ def _sync_setting_req(self, endpoints):
141142
sub_entry.topic.name = topic
142143
sub_entry.topic.resource_namespace = self.client_configuration.namespace
143144
sub_entry.expression.type = expression.filter_type
145+
sub_entry.expression.expression = expression.expression
144146

145147
settings = Settings()
146148
settings.client_type = self.client_type
147149
settings.access_point.CopyFrom(endpoints.endpoints)
148150
settings.request_timeout.seconds = self.client_configuration.request_timeout
149151
settings.subscription.CopyFrom(subscription)
150152
settings.user_agent.language = 6
151-
settings.user_agent.version = "5.0.1.1"
153+
settings.user_agent.version = Misc.sdk_version()
152154
settings.user_agent.platform = Misc.get_os_description()
153155
settings.user_agent.hostname = Misc.get_local_ip()
154156
settings.metric.on = False

python/rocketmq/v5/model/message.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ def body(self, body):
160160

161161
@topic.setter
162162
def topic(self, topic):
163+
if topic is None or topic.strip() == '':
164+
raise IllegalArgumentException("topic has not been set yet")
163165
if Misc.is_valid_topic(topic):
164166
self.__topic = topic
165167
else:

0 commit comments

Comments
 (0)