intersect-sdk-common 0.9.2__tar.gz → 0.9.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/PKG-INFO +1 -1
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/pyproject.toml +1 -1
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/brokers/amqp_client.py +32 -27
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/brokers/mqtt_client.py +16 -13
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/control_plane_manager.py +30 -18
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/topic_handler.py +2 -2
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/README.md +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/__init__.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/config.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/constants.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/__init__.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/brokers/__init__.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/brokers/broker_client.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/definitions.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/messages/__init__.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/messages/event.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/messages/lifecycle.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/control_plane/messages/userspace.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/core_definitions.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/data_plane/__init__.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/data_plane/data_plane_manager.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/data_plane/minio_utils.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/exceptions.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/logger.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/py.typed +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/utils/__init__.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/utils/multi_flag_thread_event.py +0 -0
- {intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: intersect-sdk-common
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.3
|
|
4
4
|
Summary: Python SDK to interact with INTERSECT
|
|
5
5
|
Keywords: intersect
|
|
6
6
|
Author: Lance Drane, Marshall McDonnell, Seth Hitefield, Andrew Ayres, Gregory Cage, Jesse McGaha, Robert Smith, Gavin Wiggins, Michael Brim, Rick Archibald, Addi Malviya Thakur
|
|
@@ -18,7 +18,7 @@ readme = "README.md"
|
|
|
18
18
|
license = { text = "BSD-3-Clause" }
|
|
19
19
|
requires-python = ">=3.10,<4.0"
|
|
20
20
|
keywords = ["intersect"]
|
|
21
|
-
version = "0.9.
|
|
21
|
+
version = "0.9.3"
|
|
22
22
|
classifiers = [
|
|
23
23
|
"Programming Language :: Python :: 3",
|
|
24
24
|
"Programming Language :: Python :: 3.10",
|
|
@@ -23,14 +23,12 @@ from ...utils.multi_flag_thread_event import MultiFlagThreadEvent
|
|
|
23
23
|
from .broker_client import BrokerClient
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
|
-
from collections.abc import Callable
|
|
27
|
-
|
|
28
26
|
from pika.channel import Channel
|
|
29
27
|
from pika.frame import Frame
|
|
30
28
|
from pika.spec import Basic, BasicProperties
|
|
31
29
|
|
|
30
|
+
from ..control_plane_manager import ControlPlaneManager
|
|
32
31
|
from ..definitions import MessageCallback
|
|
33
|
-
from ..topic_handler import TopicHandler
|
|
34
32
|
|
|
35
33
|
|
|
36
34
|
_AMQP_MAX_RETRIES = 10
|
|
@@ -95,8 +93,7 @@ class AMQPClient(BrokerClient):
|
|
|
95
93
|
port: int,
|
|
96
94
|
username: str,
|
|
97
95
|
password: str,
|
|
98
|
-
|
|
99
|
-
find_wildcard_handler: Callable[[str], TopicHandler | None],
|
|
96
|
+
control_plane_manager: ControlPlaneManager,
|
|
100
97
|
is_root: bool,
|
|
101
98
|
) -> None:
|
|
102
99
|
"""The default constructor.
|
|
@@ -106,8 +103,7 @@ class AMQPClient(BrokerClient):
|
|
|
106
103
|
port: port number of AMQP broker
|
|
107
104
|
username: username credentials for AMQP broker
|
|
108
105
|
password: password credentials for AMQP broker
|
|
109
|
-
|
|
110
|
-
find_wildcard_handler: callback function which gets the wildcard topic handler from the channel manager
|
|
106
|
+
control_plane_manager: reference to the ControlPlaneManager instance, remember to ONLY use functions which do not mutate state
|
|
111
107
|
is_root: Whether or not the client can configure exchanges and queues themselves (core services), or if this must be delegated to a Core Service (SDK Clients/Services)
|
|
112
108
|
"""
|
|
113
109
|
self._connection_params = pika.ConnectionParameters(
|
|
@@ -132,11 +128,11 @@ class AMQPClient(BrokerClient):
|
|
|
132
128
|
self._thread: threading.Thread | None = None
|
|
133
129
|
|
|
134
130
|
# Callback to the topics_to_handler list inside of
|
|
135
|
-
self.
|
|
136
|
-
self._find_wildcard_handler = find_wildcard_handler
|
|
131
|
+
self._control_plane_manager = control_plane_manager
|
|
137
132
|
|
|
138
133
|
# mapping of topics to callables which can unsubscribe from the topic
|
|
139
134
|
self._topics_to_consumer_tags: dict[str, _ConsumerTagInfo] = {}
|
|
135
|
+
"""NOTE: separators for topics in this object is '.' , not '/' """
|
|
140
136
|
self._consumer_tags_to_threads: dict[str, threading.Thread] = {}
|
|
141
137
|
|
|
142
138
|
self._should_disconnect = False
|
|
@@ -390,7 +386,7 @@ class AMQPClient(BrokerClient):
|
|
|
390
386
|
def _on_input_channel_open(self, channel: Channel) -> None:
|
|
391
387
|
channel_num = 1
|
|
392
388
|
self._channel_in = channel
|
|
393
|
-
# consumer channel flag can be set immediately
|
|
389
|
+
# consumer channel flag can be set immediately (NOTE: this means that code which simultaneously creates Clients and Services will need to manually wait, to ensure that each application has made the basic_consume call to the broker before messages are published)
|
|
394
390
|
self._channel_flags.set_nth_flag(channel_num)
|
|
395
391
|
cb_1 = functools.partial(self._on_channel_closed, channel_num=channel_num)
|
|
396
392
|
self._channel_in.add_on_close_callback(cb_1)
|
|
@@ -403,17 +399,7 @@ class AMQPClient(BrokerClient):
|
|
|
403
399
|
callback=cb_2,
|
|
404
400
|
)
|
|
405
401
|
else:
|
|
406
|
-
|
|
407
|
-
amqp_topic = _hierarchy_2_amqp(topic)
|
|
408
|
-
cb = functools.partial(
|
|
409
|
-
self._setup_basic_qos,
|
|
410
|
-
None,
|
|
411
|
-
channel=channel,
|
|
412
|
-
topic=amqp_topic,
|
|
413
|
-
persist=topic_handler.topic_persist,
|
|
414
|
-
queue_name=topic_handler.queue_name,
|
|
415
|
-
)
|
|
416
|
-
self._connection.ioloop.add_callback_threadsafe(cb)
|
|
402
|
+
self._create_all_queues(channel)
|
|
417
403
|
|
|
418
404
|
def _on_exchange_declareok(self, _unused_frame: Frame, channel: Channel) -> None:
|
|
419
405
|
"""Create a queue on the broker (called from AMQP).
|
|
@@ -425,7 +411,17 @@ class AMQPClient(BrokerClient):
|
|
|
425
411
|
_unused_frame: response from declaring the exchange on the broker (irrelevant).
|
|
426
412
|
channel: The Channel being instantiated.
|
|
427
413
|
"""
|
|
428
|
-
|
|
414
|
+
self._create_all_queues(channel)
|
|
415
|
+
|
|
416
|
+
def _create_all_queues(self, channel: Channel) -> None:
|
|
417
|
+
"""Create queues for all subscription channels on the broker.
|
|
418
|
+
|
|
419
|
+
This should only be called once we've verified that the exchange exists.
|
|
420
|
+
|
|
421
|
+
Args:
|
|
422
|
+
channel: The Channel being instantiated.
|
|
423
|
+
"""
|
|
424
|
+
for topic, topic_handler in self._control_plane_manager.get_all_subscription_channels():
|
|
429
425
|
amqp_topic = _hierarchy_2_amqp(topic)
|
|
430
426
|
cb = functools.partial(
|
|
431
427
|
self._create_queue,
|
|
@@ -456,6 +452,7 @@ class AMQPClient(BrokerClient):
|
|
|
456
452
|
queue=queue_name
|
|
457
453
|
if persist
|
|
458
454
|
else '', # if we're transient, let the broker generate a name for us
|
|
455
|
+
passive=not self._is_root,
|
|
459
456
|
durable=persist,
|
|
460
457
|
exclusive=not persist, # transient queues can be exclusive
|
|
461
458
|
callback=cb,
|
|
@@ -597,17 +594,25 @@ class AMQPClient(BrokerClient):
|
|
|
597
594
|
channel.basic_ack(basic_deliver.delivery_tag)
|
|
598
595
|
return
|
|
599
596
|
|
|
600
|
-
|
|
601
|
-
|
|
597
|
+
amqp_routing_key_rep = basic_deliver.routing_key
|
|
598
|
+
manager_routing_key_rep = _amqp_2_hierarchy(basic_deliver.routing_key)
|
|
599
|
+
topic_handler = self._control_plane_manager.get_non_wildcard_subscription_channels().get(
|
|
600
|
+
manager_routing_key_rep
|
|
601
|
+
)
|
|
602
602
|
if not topic_handler:
|
|
603
603
|
# we may have included the topic in one of our wildcard handlers
|
|
604
|
-
|
|
604
|
+
wildcard_result = self._control_plane_manager.get_wildcard_topic_and_topic_handler(
|
|
605
|
+
manager_routing_key_rep
|
|
606
|
+
)
|
|
607
|
+
if wildcard_result:
|
|
608
|
+
manager_routing_key_rep, topic_handler = wildcard_result
|
|
609
|
+
amqp_routing_key_rep = _hierarchy_2_amqp(manager_routing_key_rep)
|
|
605
610
|
if topic_handler:
|
|
606
|
-
consumer_tag_info = self._topics_to_consumer_tags.get(
|
|
611
|
+
consumer_tag_info = self._topics_to_consumer_tags.get(amqp_routing_key_rep)
|
|
607
612
|
if not consumer_tag_info:
|
|
608
613
|
logger.error(
|
|
609
614
|
'Could not fetch consumer tag for topic %s, please inform an INTERSECT-SDK developer that you saw this message',
|
|
610
|
-
|
|
615
|
+
amqp_routing_key_rep,
|
|
611
616
|
)
|
|
612
617
|
return
|
|
613
618
|
while not consumer_tag_info.consumer_tag_obtained():
|
|
@@ -22,12 +22,10 @@ from ...logger import logger
|
|
|
22
22
|
from .broker_client import BrokerClient
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
25
|
-
from collections.abc import Callable
|
|
26
|
-
|
|
27
25
|
from paho.mqtt.client import DisconnectFlags
|
|
28
26
|
from paho.mqtt.reasoncodes import ReasonCode
|
|
29
27
|
|
|
30
|
-
from ..
|
|
28
|
+
from ..control_plane_manager import ControlPlaneManager
|
|
31
29
|
|
|
32
30
|
|
|
33
31
|
_MQTT_MAX_RETRIES = 10
|
|
@@ -37,7 +35,8 @@ _MQTT_MAX_RETRIES = 10
|
|
|
37
35
|
# this will be a breaking change, so only add it when ready to break
|
|
38
36
|
def _hierarchy_2_mqtt(hierarchy: str) -> str:
|
|
39
37
|
"""Take the hierarchy string format saved in the Service and map it to the MQTT topic format. Currently just covers wildcards."""
|
|
40
|
-
return hierarchy.replace('#', '+')
|
|
38
|
+
# return hierarchy.replace('#', '+')
|
|
39
|
+
return hierarchy.replace('*', '+')
|
|
41
40
|
|
|
42
41
|
|
|
43
42
|
class MQTTClient(BrokerClient):
|
|
@@ -61,8 +60,7 @@ class MQTTClient(BrokerClient):
|
|
|
61
60
|
port: int,
|
|
62
61
|
username: str,
|
|
63
62
|
password: str,
|
|
64
|
-
|
|
65
|
-
find_wildcard_handler: Callable[[str], TopicHandler | None],
|
|
63
|
+
control_plane_manager: ControlPlaneManager,
|
|
66
64
|
uid: str | None = None,
|
|
67
65
|
) -> None:
|
|
68
66
|
"""The default constructor.
|
|
@@ -72,8 +70,7 @@ class MQTTClient(BrokerClient):
|
|
|
72
70
|
port: port number of MQTT broker
|
|
73
71
|
username: username credentials for MQTT broker
|
|
74
72
|
password: password credentials for MQTT broker
|
|
75
|
-
|
|
76
|
-
find_wildcard_handler: callback function which gets the wildcard topic handler from the channel manager
|
|
73
|
+
control_plane_manager: reference to the ControlPlaneManager instance, remember to ONLY use functions which do not mutate state
|
|
77
74
|
uid: A string representing the unique id to identify the client.
|
|
78
75
|
"""
|
|
79
76
|
# Unique id for the MQTT broker to associate this client with
|
|
@@ -97,8 +94,7 @@ class MQTTClient(BrokerClient):
|
|
|
97
94
|
self._connected_flag = threading.Event()
|
|
98
95
|
|
|
99
96
|
# ConnectionManager callable state
|
|
100
|
-
self.
|
|
101
|
-
self._find_wildcard_handler = find_wildcard_handler
|
|
97
|
+
self._control_plane_manager = control_plane_manager
|
|
102
98
|
|
|
103
99
|
# MQTT v3.1.1 automatically downgrades a QOS which is too high (good), but MQTT v5 will terminate the connection (bad)
|
|
104
100
|
# see https://github.com/rabbitmq/rabbitmq-server/discussions/11842
|
|
@@ -204,10 +200,17 @@ class MQTTClient(BrokerClient):
|
|
|
204
200
|
message: MQTT message
|
|
205
201
|
"""
|
|
206
202
|
# NOTE: should not need to convert the MQTT topic to the protocol agnostic representation, as we only change the wildcard format (which won't show up as the message topic)
|
|
207
|
-
|
|
203
|
+
inmem_topic = message.topic
|
|
204
|
+
topic_handler = self._control_plane_manager.get_non_wildcard_subscription_channels().get(
|
|
205
|
+
inmem_topic
|
|
206
|
+
)
|
|
208
207
|
if not topic_handler:
|
|
209
208
|
# we may have included the topic in one of our wildcard handlers
|
|
210
|
-
|
|
209
|
+
wildcard_result = self._control_plane_manager.get_wildcard_topic_and_topic_handler(
|
|
210
|
+
inmem_topic
|
|
211
|
+
)
|
|
212
|
+
if wildcard_result:
|
|
213
|
+
_, topic_handler = wildcard_result
|
|
211
214
|
# Note that if we return prior to the callback, there will be no reply message
|
|
212
215
|
if not topic_handler:
|
|
213
216
|
logger.warning('Incompatible message topic %s, rejecting message', message.topic)
|
|
@@ -298,7 +301,7 @@ class MQTTClient(BrokerClient):
|
|
|
298
301
|
self._max_supported_qos = properties.MaximumQoS
|
|
299
302
|
|
|
300
303
|
self._connected_flag.set()
|
|
301
|
-
for topic, topic_handler in self.
|
|
304
|
+
for topic, topic_handler in self._control_plane_manager.get_all_subscription_channels():
|
|
302
305
|
self.subscribe(topic, topic_handler.topic_persist)
|
|
303
306
|
else:
|
|
304
307
|
# This will generally suggest a misconfiguration
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Wrapper around interacting with the control plane, which may be multiple brokers."""
|
|
2
2
|
|
|
3
|
+
import itertools
|
|
3
4
|
import re
|
|
4
|
-
from collections.abc import Callable
|
|
5
5
|
|
|
6
6
|
from ..config import ControlPlaneConfig
|
|
7
7
|
from ..exceptions import IntersectSetupError
|
|
@@ -23,8 +23,7 @@ _CHANNEL_REGEX = re.compile(r'^[a-zA-Z0-9*/-]+[a-zA-Z0-9*#/-]$')
|
|
|
23
23
|
|
|
24
24
|
def _create_control_provider(
|
|
25
25
|
config: ControlPlaneConfig,
|
|
26
|
-
|
|
27
|
-
find_wildcard_handler: Callable[[str], TopicHandler | None],
|
|
26
|
+
control_plane_manager: 'ControlPlaneManager',
|
|
28
27
|
) -> BrokerClient:
|
|
29
28
|
if config.protocol == 'amqp0.9.1':
|
|
30
29
|
from .brokers.amqp_client import ( # noqa: PLC0415 (lazy load all AMQP modules)
|
|
@@ -36,8 +35,7 @@ def _create_control_provider(
|
|
|
36
35
|
port=config.port or 5672,
|
|
37
36
|
username=config.username,
|
|
38
37
|
password=config.password,
|
|
39
|
-
|
|
40
|
-
find_wildcard_handler=find_wildcard_handler,
|
|
38
|
+
control_plane_manager=control_plane_manager,
|
|
41
39
|
is_root=config.is_root,
|
|
42
40
|
)
|
|
43
41
|
|
|
@@ -49,8 +47,7 @@ def _create_control_provider(
|
|
|
49
47
|
port=config.port or 1883,
|
|
50
48
|
username=config.username,
|
|
51
49
|
password=config.password,
|
|
52
|
-
|
|
53
|
-
find_wildcard_handler=find_wildcard_handler,
|
|
50
|
+
control_plane_manager=control_plane_manager,
|
|
54
51
|
)
|
|
55
52
|
|
|
56
53
|
|
|
@@ -68,10 +65,7 @@ class ControlPlaneManager:
|
|
|
68
65
|
queue_name_generator should be a hardcoded value for Core Services, the SDK should provide its own function to generate queue names.
|
|
69
66
|
"""
|
|
70
67
|
self._control_providers = [
|
|
71
|
-
_create_control_provider(
|
|
72
|
-
config, self.get_subscription_channels, self.get_wildcard_topic_handler
|
|
73
|
-
)
|
|
74
|
-
for config in control_configs
|
|
68
|
+
_create_control_provider(config, self) for config in control_configs
|
|
75
69
|
]
|
|
76
70
|
|
|
77
71
|
# flag which indicates if we SHOULD be connected.
|
|
@@ -142,29 +136,47 @@ class ControlPlaneManager:
|
|
|
142
136
|
provider.unsubscribe(channel)
|
|
143
137
|
return True
|
|
144
138
|
|
|
145
|
-
def
|
|
146
|
-
"""Get
|
|
139
|
+
def get_non_wildcard_subscription_channels(self) -> dict[str, TopicHandler]:
|
|
140
|
+
"""Get primary subscription channels.
|
|
147
141
|
|
|
148
|
-
These channels cannot be wildcards, and incoming topics must match the channel topics exactly.
|
|
142
|
+
These channels cannot be wildcards, and incoming topics must match the channel topics exactly.
|
|
143
|
+
|
|
144
|
+
This function is safe to call from the broker clients, as it does not mutate state.
|
|
149
145
|
|
|
150
146
|
Returns:
|
|
151
147
|
the dictionary of topics to topic information
|
|
152
148
|
"""
|
|
153
149
|
return self._topics_to_handlers
|
|
154
150
|
|
|
155
|
-
def
|
|
151
|
+
def get_wildcard_topic_and_topic_handler(self, topic: str) -> tuple[str, TopicHandler] | None:
|
|
156
152
|
"""Get the wildcard topic handler for a given topic, if it exists.
|
|
157
153
|
|
|
158
154
|
This is an inefficient lookup, so should only be used if we fail to find a non-wildcard match for an incoming topic. Note that this function gets accessed as a callback from the direct broker implementations.
|
|
159
155
|
|
|
156
|
+
This function is safe to call from the broker clients, as it does not mutate state.
|
|
157
|
+
|
|
158
|
+
Params:
|
|
159
|
+
topic: the topic for an incoming message (this will not have any wildcards in it)
|
|
160
|
+
|
|
160
161
|
Returns:
|
|
161
|
-
the
|
|
162
|
+
if a match found: the wildcard string configured application-side to match the topic parameter, and the topic handler associated with the topic
|
|
163
|
+
if no match found: None
|
|
162
164
|
"""
|
|
163
|
-
for topic_handler in self._wildcards.
|
|
165
|
+
for wildcard, topic_handler in self._wildcards.items():
|
|
164
166
|
if topic_handler.does_topic_match(topic):
|
|
165
|
-
return topic_handler
|
|
167
|
+
return wildcard, topic_handler
|
|
166
168
|
return None
|
|
167
169
|
|
|
170
|
+
def get_all_subscription_channels(self) -> itertools.chain[tuple[str, TopicHandler]]:
|
|
171
|
+
"""Get all subscription channels, including wildcard channels.
|
|
172
|
+
|
|
173
|
+
This function is safe to call from the broker clients, as it does not mutate state.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
an iterator which yields tuples of (channel, topic handler) for all channels, including wildcards. Note that wildcard channels will be returned in no particular order, and may be interspersed with non-wildcard channels.
|
|
177
|
+
"""
|
|
178
|
+
return itertools.chain(self._topics_to_handlers.items(), self._wildcards.items())
|
|
179
|
+
|
|
168
180
|
def connect(self) -> None:
|
|
169
181
|
"""Connect to all configured brokers.
|
|
170
182
|
|
|
@@ -46,8 +46,8 @@ class TopicHandler:
|
|
|
46
46
|
# match any sequence of 0 or more words (make sure to allow for the separator)
|
|
47
47
|
regex_builder.append('[a-zA-Z0-9/-]*')
|
|
48
48
|
elif char == '/':
|
|
49
|
-
# in-memory topics use '/' as the separator,
|
|
50
|
-
regex_builder.append('
|
|
49
|
+
# in-memory topics use '/' as the separator, it is the protocol handler's responsibility to convert topics to use '/' as the separator
|
|
50
|
+
regex_builder.append('/')
|
|
51
51
|
else:
|
|
52
52
|
# ordinary character
|
|
53
53
|
regex_builder.append(char)
|
|
File without changes
|
{intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/__init__.py
RENAMED
|
File without changes
|
{intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/config.py
RENAMED
|
File without changes
|
{intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/constants.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/exceptions.py
RENAMED
|
File without changes
|
{intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/logger.py
RENAMED
|
File without changes
|
|
File without changes
|
{intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{intersect_sdk_common-0.9.2 → intersect_sdk_common-0.9.3}/src/intersect_sdk_common/version.py
RENAMED
|
File without changes
|