Module remoc::rch

source ·
Available on crate feature rch only.
Expand description

Remote channels.

This module contains channels that can be used to exchange data of arbitrary type with a remote endpoint.

The data type must be serializable and deserializable by serde and sendable across thread boundaries. The RemoteSend trait is implemented automatically for all types that fulfill these requirements.

§Establishing a channel connection with a remote endpoint

Except for a base channel, a channel connection is established by sending the Sender or Receiver half of a channel to a remote endpoint over an already existing channel. The transmitted channel-half can also be part of a larger object, such as a struct, tuple or enum. Most channel types can even be forwarded over multiple connections.

The primary purpose of a base channel is to provide an initial channel after establishing a connection over a physical transport. In most cases there is no need to create it directly and you will probably only use it after it has been returned from an initial connect function.

§Channel types

Broadcast, MPSC, oneshot and watch channels are closely modelled after the channels found in tokio::sync. They also work when both halves of the channel are local and can be forwarded over multiple connections.

An local/remote channel is a more restricted version of an MPSC channel. It does not support forwarding and exactly one half of it must be on a remote endpoint. Its benefit is, that it does not spawn an async task and thus uses less resources. When in doubt use an MPSC channel instead.

A binary channel can be used to exchange binary data over a channel. It skips serialization and deserialization and thus is more efficient for binary data, especially when using text codecs such as JSON. It does support forwarding. However, at least one half of it must be on a remote endpoint.

§Acknowledgements and connection latency

The channels do not wait for acknowledgement of transmitted values. Thus, the next value can be queued for transmission before the previous value has been received by the remote endpoint. Hence, throughput is unaffected by the connection roundtrip time.

A successful send does not guarantee that the transmitted value will be received by the remote endpoint. However, values cannot be lost intermittently, i.e. if a transmission error occurs on the underlying physical connection the whole chmux connection will be terminated eventually and sending will fail.

If you need confirmation for every sent value, consider sending a oneshot::Sender<()> along with it (for example as a tuple). The remote endpoint can then send back an empty message as confirmation over the oneshot channel after it has processed the received value.

§Size considerations

The size of the objects exchanged is not limited. If the object is small enough it is first serialized into a buffer and then sent as one message to the remote endpoint. For larger objects, a serialization thread is spawned and the message is sent chunk-by-chunk to avoid the need for a large temporary memory buffer. Deserialization is also performed on-the-fly as data is received for large objects.

Large values are always sent in chunks, so that one channel does not block other channels for a long period of time.

To avoid denial of service attacks when you exchange data with untrusted remote endpoints, make sure that an object cannot grow to infinite size during deserialization. For example, avoid using containers of unlimited size like Vec or HashMap in your data structure or limit their maximum size during deserialization by applying the #[serde(deserialize_with="...")] attribute to the fields containing them.

§Static buffer size configuration for received channel-halves

This is used to specify the local buffer size (in items) via a const generic type parameter when the sender or receiver half of a channel is received.

The default buffer size is DEFAULT_BUFFER, which is currently 2 items. It can be increased to improve performance, but this will also increase the maximum amount of memory used per channel. Setting the buffer size too high must be avoided, since this can lead to the program running out of memory.

§Error handling

During sending it is often useful to treat errors that occur due to the disconnection, either graceful or non-graceful, of the remote endpoint as an indication that the receiver is not interested anymore in the transmitted data, rather than a hard error. To avoid complicated error checks in your code, you can use SendResultExt::into_disconnected to query whether a send error occurred due to the above cause and exit the sending process gracefully.

Modules§

  • A channel that exchanges values of arbitrary type with a remote endpoint and is primarily used as the initial channel after establishing a connection with a remote endpoint.
  • A channel that exchanges binary data with a remote endpoint.
  • A multi-producer, multi-consumer broadcast queue with receivers that may be located on remote endpoints.
  • A channel that exchanges values of arbitrary type with a remote endpoint and is established by sending exactly one half of it over an existing channel.
  • Multi producer single customer remote channel.
  • A one-shot channel is used for sending a single message between asynchronous, remote tasks.
  • A single-producer, multi-consumer remote channel that only retains the last sent value.

Enums§

Constants§

  • Default buffer size in items, when the sender or receiver half of a channel is received.
  • Default maximum allowed item size for sending and receiving items over remote channels.

Traits§

  • Common functions to query send errors for details.
  • Common functions to query results of send operations for details.