mirror of
https://github.com/django/daphne.git
synced 2025-07-05 12:23:19 +03:00
Update ASGI spec with single-reader channel
This commit is contained in:
parent
3c5c09d639
commit
08ecffe107
|
@ -100,7 +100,7 @@ contain only the following types to ensure serializability:
|
|||
|
||||
Channels are identified by a unicode string name consisting only of ASCII
|
||||
letters, ASCII numerical digits, periods (``.``), dashes (``-``) and
|
||||
underscores (``_``), plus an optional prefix character (see below).
|
||||
underscores (``_``), plus an optional type character (see below).
|
||||
|
||||
Channels are a first-in, first out queue with at-most-once delivery
|
||||
semantics. They can have multiple writers and multiple readers; only a single
|
||||
|
@ -111,8 +111,26 @@ this is necessary to achieve this restriction.
|
|||
In order to aid with scaling and network architecture, a distinction
|
||||
is made between channels that have multiple readers (such as the
|
||||
``http.request`` channel that web applications would listen on from every
|
||||
application worker process) and *process-specific channels*
|
||||
(such as a ``http.response!ABCDEF`` channel tied to a client socket).
|
||||
application worker process), *single-reader channels* that are read from a
|
||||
single unknown location (such as ``http.request.body?ABCDEF``), and
|
||||
*process-specific channels* (such as a ``http.response!ABCDEF`` channel
|
||||
tied to a client socket).
|
||||
|
||||
*Normal channel* names contain no type characters, and can be routed however
|
||||
the backend wishes; in particular, they do not have to appear globally
|
||||
consistent, and backends may shard their contents out to different servers
|
||||
so that a querying client only sees some portion of the messages. Calling
|
||||
``receive_many`` on these channels does not guarantee that you will get the
|
||||
messages in order or that you will get anything if the channel is non-empty.
|
||||
|
||||
*Single-reader channel* names contain an exclamation mark
|
||||
(``?``) character in order to indicate to the channel layer that it must make
|
||||
these channels appear globally consistent. The ``?`` is always preceded by
|
||||
the main channel name (e.g. ``http.response.body``) and followed by a
|
||||
random portion. Channel layers may use the random portion to help pin the
|
||||
channel to a server, but reads from this channel by a single process must
|
||||
always be in-order and return messages if the channel is non-empty. These names
|
||||
must be generated by the ``new_channel`` call.
|
||||
|
||||
*Process-specific channel* names contain an exclamation mark
|
||||
(``!``) character in order to indicate to the channel layer that it may
|
||||
|
@ -124,16 +142,19 @@ per-client/random portion - channel layers can split on the ``!`` and use just
|
|||
the right hand part to route if they desire, or can ignore it if they don't
|
||||
need to use different routing rules. Even if the right hand side contains
|
||||
client routing information, it must still contain random parts too so that
|
||||
each call to ``new_channel`` returns a new, unused name.
|
||||
each call to ``new_channel`` returns a new, unused name. These names
|
||||
must be generated by the ``new_channel`` call; they are guaranteed to only
|
||||
be read from the same process that calls ``new_channel``.
|
||||
|
||||
Messages should expire after a set time sitting unread in a channel;
|
||||
the recommendation is one minute, though the best value depends on the
|
||||
channel layer and the way it is deployed.
|
||||
|
||||
The maximum message size is 1MB; if more data than this needs to be transmitted
|
||||
it must be chunked or placed onto its own process-specific channel (see how
|
||||
HTTP request bodies are done, for example). All channel layers must support
|
||||
messages up to this size.
|
||||
The maximum message size is 1MB if the message were encoded as JSON;
|
||||
if more data than this needs to be transmitted it must be chunked or placed
|
||||
onto its own single-reader or process-specific channel (see how HTTP request
|
||||
bodies are done, for example). All channel layers must support messages up
|
||||
to this size, but protocol specifications are encouraged to keep well below it.
|
||||
|
||||
|
||||
Handling Protocols
|
||||
|
@ -253,9 +274,9 @@ and the vast majority of application code will not need to deal with this
|
|||
problem. If ordering of incoming packets matters for a protocol, they should
|
||||
be annotated with a packet number (as WebSocket is in this specification).
|
||||
|
||||
Single-reader channels, such as those used for response channels back to
|
||||
clients, are not subject to this problem; a single reader must always
|
||||
receive messages in channel order.
|
||||
Single-reader and process-specific channels, such as those used for response
|
||||
channels back to clients, are not subject to this problem; a single reader
|
||||
on these must always receive messages in channel order.
|
||||
|
||||
|
||||
Capacity
|
||||
|
@ -299,14 +320,13 @@ A *channel layer* must provide an object with these attributes
|
|||
|
||||
* ``new_channel(pattern)``, a callable that takes a unicode string pattern,
|
||||
and returns a new valid channel name that does not already exist, by
|
||||
adding a unicode string after the ``!`` character in ``pattern``,
|
||||
adding a unicode string after the ``!`` or ``?`` character in ``pattern``,
|
||||
and checking for existence of that name in the channel layer. The ``pattern``
|
||||
MUST end with ``!`` or this function must error. This is not always called
|
||||
prior to a message being sent on a channel, and cannot be used for
|
||||
channel initialization. ``new_channel`` must be called on the same channel
|
||||
layer that intends to read the channel with ``receive_many``; any other
|
||||
channel layer instance may not receive messages on this channel due to
|
||||
client-routing portions of the appended string.
|
||||
MUST end with ``!`` or ``?`` or this function must error. If the character
|
||||
is ``!``, making it a process-specific channel, ``new_channel`` must be
|
||||
called on the same channel layer that intends to read the channel with
|
||||
``receive_many``; any other channel layer instance may not receive
|
||||
messages on this channel due to client-routing portions of the appended string.
|
||||
|
||||
* ``MessageTooLarge``, the exception raised when a send operation fails
|
||||
because the encoded message is over the layer's size limit.
|
||||
|
@ -366,7 +386,7 @@ Channel Semantics
|
|||
Channels **must**:
|
||||
|
||||
* Preserve ordering of messages perfectly with only a single reader
|
||||
and writer, and preserve as much as possible in other cases.
|
||||
and writer if the channel is a *single-reader* or *process-specific* channel.
|
||||
|
||||
* Never deliver a message more than once.
|
||||
|
||||
|
@ -379,6 +399,9 @@ Channels **must**:
|
|||
|
||||
* Have a maximum name length of at least 100 bytes.
|
||||
|
||||
They should attempt to preserve ordering in all cases as much as possible,
|
||||
but perfect global ordering is obviously not possible in the distributed case.
|
||||
|
||||
They are not expected to deliver all messages, but a success rate of at least
|
||||
99.99% is expected under normal circumstances. Implementations may want to
|
||||
have a "resilience testing" mode where they deliberately drop more messages
|
||||
|
@ -520,7 +543,7 @@ Keys:
|
|||
If ``more_body`` is set, treat as start of body and concatenate
|
||||
on further chunks.
|
||||
|
||||
* ``more_body``: Channel name that contains
|
||||
* ``more_body``: Name of a single-reader channel (containing ``?``) that contains
|
||||
Request Body Chunk messages representing a large request body.
|
||||
Optional, defaults to ``None``. Chunks append to ``body`` if set. Presence of
|
||||
a channel indicates at least one Request Body Chunk message needs to be read,
|
||||
|
@ -541,7 +564,7 @@ Request Body Chunk
|
|||
|
||||
Must be sent after an initial Response.
|
||||
|
||||
Channel: ``http.request.body!``
|
||||
Channel: ``http.request.body?``
|
||||
|
||||
Keys:
|
||||
|
||||
|
@ -845,7 +868,9 @@ limitation that they only use the following characters:
|
|||
* Hyphen ``-``
|
||||
* Underscore ``_``
|
||||
* Period ``.``
|
||||
* Exclamation mark ``!`` (only to deliniate process-specific channel names,
|
||||
* Question mark ``?`` (only to delineiate single-reader channel names,
|
||||
and only one per name)
|
||||
* Exclamation mark ``!`` (only to delineate process-specific channel names,
|
||||
and only one per name)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user