Skip to content

Commit

Permalink
Distinguish the different meanings of a "message"
Browse files Browse the repository at this point in the history
The context for this suggested change is ably-js#1398. There, I pointed out
that the specification’s current signatures for `publish` (specifically, the
overloads that accept a `Message` or an array thereof) do not seem to match how
we’re expecting these methods to be used in real life. This is because
`Message`’s `id` and `timestamp` properties are specified as non-optional,
meaning that a user calling `publish` would need to populate these properties.
In reality, we do not expect a user to populate these properties — they are
usually generated by the Ably service.

The easiest way to solve this would be to be to make these properties optional.
However, doing so would unnecessarily remove some useful type information for
_recipients_ of messages — the type system would no longer communicate that
these properties are guaranteed to be populated in a message emitted by the
library.

In this PR, I’m proposing that we distinguish between three separate
concepts of a "message", which I think are perhaps currently being incorrectly
conflated:

1. The data type that a user of the library passes to the `publish` methods

2. The data type that the library emits from methods that expose messages
   published on a channel

3. The data type that describes a serialized message that is transmitted over
   the wire

I’ve named the first one OutgoingMessage, the second one IncomingMessage, and I
believe that the third belongs in the documentation for the Ably protocol, not
the library specification.

OutgoingMessage and IncomingMessage differ from the existing `Message` type in
the following ways:

- OutgoingMessage’s `id` and `timestamp` properties are now optional
- OutgoingMessage does not have `fromEncoded*` methods

- IncomingMessage’s `connnectionId` property is now non-optional (i.e. we are
  now able to provide stronger type information for this property) — I need to
  double-check whether this property is actually guaranteed to be populated by
  the library; my reading of TM2c and RTL6f suggested that it is, but I’m not
  sure if TM2c’s "the @connectionId@ of the encapsulating @ProtocolMessage@" is
  guaranteed to be populated.
- IncomingMessage does not have constructors

I have not yet introduced spec points for these two new types — I will do so if
there is a consensus to move forwards with this approach. For now, see the
changes to the IDL.

Other thoughts:

- I think that, similarly to the Message wire type, the ProtocolMessage type
  should also only be described by the protocol documentation, and not the
  feature spec.

- If we do choose to start leaning more heavily on the protocol documentation,
  then we’ll need to bring it up to date — it looks like it hasn’t been touched
  in quite some time and still mentions `connectionSerial`, for example.

- I’ve kept the exact same list of properties in IncomingMessage and
  OutgoingMessage, since my reading of RSL1j is that a user publishing a
  message should be able to populate any of the properties of the message that
  eventually gets sent over the wire. But if that’s not the case, then we may be
  able to remove some properties from `OutgoingMessage`.
  • Loading branch information
lawrence-forooghian committed Jul 19, 2023
1 parent a7949ec commit 8a1d221
Showing 1 changed file with 57 additions and 42 deletions.
Loading

0 comments on commit 8a1d221

Please sign in to comment.