From 118acf77b8b20ac6451df1cdc470738c9c5ee2df Mon Sep 17 00:00:00 2001 From: Aaron Heise <5148966+acehoss@users.noreply.github.com> Date: Mon, 27 Feb 2023 21:10:28 -0600 Subject: [PATCH] Fix up documentation even more --- RNS/Channel.py | 60 ++++++++++++++++++++++++++++----------- docs/source/examples.rst | 12 ++++++++ docs/source/reference.rst | 2 +- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/RNS/Channel.py b/RNS/Channel.py index a781697..fba65e1 100644 --- a/RNS/Channel.py +++ b/RNS/Channel.py @@ -134,8 +134,9 @@ class MessageBase(abc.ABC): MSGTYPE = None """ Defines a unique identifier for a message class. - ``MSGTYPE`` must be unique within all classes sent over a channel. - ``MSGTYPE`` must be < ``0xf000``. Values >= ``0xf000`` are reserved. + + * Must be unique within all classes registered with a ``Channel`` + * Must be less than ``0xf000``. Values greater than or equal to ``0xf000`` are reserved. """ @abstractmethod @@ -148,7 +149,7 @@ class MessageBase(abc.ABC): raise NotImplemented() @abstractmethod - def unpack(self, raw): + def unpack(self, raw: bytes): """ Populate message from binary representation @@ -196,14 +197,29 @@ class Envelope: class Channel(contextlib.AbstractContextManager): """ - Channel provides reliable delivery of messages over + Provides reliable delivery of messages over a link. - Channel is not meant to be instantiated - directly, but rather obtained from a Link using the - get_channel() function. + ``Channel`` differs from ``Request`` and + ``Resource`` in some important ways: - :param outlet: Outlet object to use for transport + **Continuous** + Messages can be sent or received as long as + the ``Link`` is open. + **Bi-directional** + Messages can be sent in either direction on + the ``Link``; neither end is the client or + server. + **Size-constrained** + Messages must be encoded into a single packet. + + ``Channel`` is similar to ``Packet``, except that it + provides reliable delivery (automatic retries) as well + as a structure for exchanging several types of + messages over the ``Link``. + + ``Channel`` is not instantiated directly, but rather + obtained from a ``Link`` with ``get_channel()``. """ def __init__(self, outlet: ChannelOutletBase): """ @@ -227,12 +243,17 @@ class Channel(contextlib.AbstractContextManager): self._shutdown() return False - def register_message_type(self, message_class: Type[MessageBase], *, is_system_type: bool = False): + def register_message_type(self, message_class: Type[MessageBase]): """ - Register a message class for reception over a channel. + Register a message class for reception over a ``Channel``. - :param message_class: Class to register. Must extend MessageBase. + Message classes must extend ``MessageBase``. + + :param message_class: Class to register """ + self._register_message_type(message_class, is_system_type=False) + + def _register_message_type(self, message_class: Type[MessageBase], *, is_system_type: bool = False): with self._lock: if not issubclass(message_class, MessageBase): raise ChannelException(CEType.ME_INVALID_MSG_TYPE, @@ -254,7 +275,10 @@ class Channel(contextlib.AbstractContextManager): def add_message_handler(self, callback: MessageCallbackType): """ Add a handler for incoming messages. A handler - has the signature ``(message: MessageBase) -> bool``. + has the following signature: + + ``(message: MessageBase) -> bool`` + Handlers are processed in the order they are added. If any handler returns True, processing of the message stops; handlers after the @@ -268,7 +292,7 @@ class Channel(contextlib.AbstractContextManager): def remove_message_handler(self, callback: MessageCallbackType): """ - Remove a handler + Remove a handler added with ``add_message_handler``. :param callback: handler to remove """ @@ -341,7 +365,7 @@ class Channel(contextlib.AbstractContextManager): def is_ready_to_send(self) -> bool: """ - Check if Channel is ready to send. + Check if ``Channel`` is ready to send. :return: True if ready """ @@ -389,9 +413,9 @@ class Channel(contextlib.AbstractContextManager): def send(self, message: MessageBase) -> Envelope: """ Send a message. If a message send is attempted and - Channel is not ready, an exception is thrown. + ``Channel`` is not ready, an exception is thrown. - :param message: an instance of a MessageBase subclass to send on the Channel + :param message: an instance of a ``MessageBase`` subclass """ envelope: Envelope | None = None with self._lock: @@ -416,7 +440,9 @@ class Channel(contextlib.AbstractContextManager): def MDU(self): """ Maximum Data Unit: the number of bytes available - for a message to consume in a single send. + for a message to consume in a single send. This + value is adjusted from the ``Link`` MDU to accommodate + message header information. :return: number of bytes available """ diff --git a/docs/source/examples.rst b/docs/source/examples.rst index 9b4428f..54c13f3 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -92,6 +92,18 @@ The *Request* example explores sendig requests and receiving responses. This example can also be found at ``_. +.. _example-channel: + +Channel +==== + +The *Channel* example explores using a ``Channel`` to send structured +data between peers of a ``Link``. + +.. literalinclude:: ../../Examples/Channel.py + +This example can also be found at ``_. + .. _example-filetransfer: Filetransfer diff --git a/docs/source/reference.rst b/docs/source/reference.rst index 6c958aa..8d519a8 100644 --- a/docs/source/reference.rst +++ b/docs/source/reference.rst @@ -132,7 +132,7 @@ This chapter lists and explains all classes exposed by the Reticulum Network Sta Channel ------ -.. autoclass:: RNS.Channel.Channel(outlet) +.. autoclass:: RNS.Channel.Channel() :members: .. _api-messsagebase: