Skip to content

Commit d842a59

Browse files
Use Notifications instead of Requests
1 parent 9d396fc commit d842a59

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

pyleco/utils/extended_data_publisher.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323
#
2424

2525
from __future__ import annotations
26+
from json import JSONDecodeError
2627
from typing import Any, Callable, Generator, Union
2728

29+
from ..json_utils.errors import JSONRPCError, NODE_UNKNOWN, RECEIVER_UNKNOWN
30+
from ..json_utils.json_objects import Notification
2831
from ..core.message import Message, MessageTypes
2932
from ..core.data_message import DataMessage
3033
from ..json_utils.rpc_generator import RPCGenerator
@@ -57,11 +60,10 @@ def convert_data_message_to_messages(
5760
self, data_message: DataMessage, receivers: Union[set[Union[bytes, str]], set[bytes]],
5861
) -> Generator[Message, Any, Any]:
5962
cid = data_message.conversation_id
60-
data = self.rpc_generator.build_request_str(method="add_subscription_message")
6163
for receiver in receivers:
6264
yield Message(
6365
receiver=receiver,
64-
data=data,
66+
data=Notification("add_subscription_message"),
6567
conversation_id=cid,
6668
additional_payload=data_message.payload,
6769
message_type=MessageTypes.JSON,
@@ -72,3 +74,32 @@ def send_message(self, message: DataMessage) -> None:
7274
for msg in self.convert_data_message_to_messages(message, self.subscribers):
7375
# ideas: change to ask and check, whether it succeeded, otherwise remove subscriber
7476
self.send_control_message(msg)
77+
78+
# TODO should unregister subscribers to which a message could not be forwarded
79+
def handle_json_error(self, message: Message) -> None:
80+
"""Unregister unavailable subscribers.
81+
82+
Call this method from the message handler, for example.
83+
"""
84+
try:
85+
data: dict[str, Any] = message.data # type: ignore
86+
except JSONDecodeError as exc:
87+
self.log.exception(f"Could not decode json message {message}", exc_info=exc)
88+
return
89+
try:
90+
self.rpc_generator.get_result_from_response(data)
91+
except JSONRPCError as exc:
92+
error_code = exc.rpc_error.code
93+
try:
94+
error_data = exc.rpc_error.data
95+
except AttributeError:
96+
return
97+
if error_code == RECEIVER_UNKNOWN:
98+
self.unregister_subscriber(error_data)
99+
if error_code == NODE_UNKNOWN:
100+
if isinstance(error_data, str):
101+
error_data = error_data.encode()
102+
for subscriber in self.subscribers:
103+
if subscriber.startswith(error_data):
104+
self.unregister_subscriber(subscriber)
105+

tests/utils/test_extended_data_publisher.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from pyleco.test import FakeContext
2828
from pyleco.core.message import Message, MessageTypes
2929
from pyleco.core.data_message import DataMessage
30+
from pyleco.json_utils.json_objects import Notification
3031
from pyleco.utils.extended_data_publisher import ExtendedDataPublisher
3132

3233

@@ -86,11 +87,10 @@ def test_unregister_subscribers(publisher: ExtendedDataPublisher):
8687
@pytest.mark.parametrize("receivers", (set(), {b"abc"}, {b"abc", b"def"}, {"string"}))
8788
def test_convert(publisher: ExtendedDataPublisher, receivers, data_message: DataMessage):
8889
msgs = publisher.convert_data_message_to_messages(data_message, receivers=receivers)
89-
assert len(receivers) == len(list(msgs)), "The lengths of receivers and messages do not match."
90-
for rec, msg in zip(receivers, msgs):
90+
for rec, msg in zip(receivers, msgs, strict=True):
9191
assert msg == Message(
9292
receiver=rec,
93-
data={"id": 1, "method": "add_subscription_message", "jsonrpc": "2.0"},
93+
data=Notification(method="add_subscription_message"),
9494
conversation_id=CID,
9595
message_type=MessageTypes.JSON,
9696
additional_payload=data_message.payload,
@@ -109,7 +109,7 @@ def test_send_message(publisher: ExtendedDataPublisher, data_message: DataMessag
109109
assert messages == [
110110
Message(
111111
"abc",
112-
data={"id": 1, "method": "add_subscription_message", "jsonrpc": "2.0"},
112+
data=Notification(method="add_subscription_message"),
113113
conversation_id=CID,
114114
message_type=MessageTypes.JSON,
115115
additional_payload=data_message.payload,

0 commit comments

Comments
 (0)