Skip to content

Commit

Permalink
doc: create ADR for Skate MQTT Hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
firestack committed Jul 9, 2024
1 parent aa8ed20 commit 3d9b684
Showing 1 changed file with 134 additions and 0 deletions.
134 changes: 134 additions & 0 deletions documentation/adr/0004-trip-modifications-mqtt-topic-structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# 4. Trip Modifications MQTT Topic Structure

Date: 2024-07-04

## Status

Draft

## Context

[With the creation of #ADR0003](./0003-use-mqtt-to-publish-trip-modifications.md),
we are trying to decide on the structure for _how_ we send and persist these
[Trip Modifications](https://gtfs.org/realtime/reference/#message-tripmodifications) between Skate and Transit Data.

We know that we'll need these messages to be available if the Transit Data
service is restarted.

## Decision

We'll use a
[topic hierarchy](https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/)
which allows us to manage individual GTFS-RT messages and update them, and does
not require that the Transit Data service has some way to persist state between
restarts.

### Topic Hierarchy
We'll nest all of our Trip Modifications related data under the
[MQTT "topic level"](https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/)
`trip_modifications`, which will be under our "topic prefix"
configured in the DevOps repo for each environment.

For Example: (spaces used for alignment, and are not part of the topic)
```
skate/prod /trip_modifications/
skate/dev /trip_modifications/
skate/dev-blue /trip_modifications/
skate/dev-green/trip_modifications/
```


For each new and unique trip modification, we'll generate a unique ID and use
that as our Trip Modification identifier, named `id`.

> [!NOTE]
> The GTFS-RT Trip Modifications spec does not currently have a ID for each modification,
> so this `ID` _will not_ appear with the Trip Modification Message.
The topic hierarchy is then formed using this ID as the topic level
```
<prefix>/trip_modifications/#{id}/
```

Then, to create or update an associated `trip_modification`, we'll use the topic
level `trip_modification`
Creating the topic
```
<prefix>/trip_modifications/#{id}/trip_modification
```

Any associated [`Shape`](https://gtfs.org/realtime/reference/#message-shape)
Messages will be published to the topic level `shape` in the hierarchy.
```
<prefix>/trip_modifications/#{id}/shape
```

On `Shape` Messages, the
[`Shape.shape_id`](https://gtfs.org/realtime/reference/#message-shape)
field will also have a unique ID generated by Skate, which will be
referenced by the corresponding Trip Modification's
[`SelectedTrips.shape_id`](https://gtfs.org/realtime/reference/#message-selectedtrips)
field.

#### Active Trip Modifications State
Messages pushed to these topics will have the
[`retain` property](https://www.hivemq.com/blog/mqtt-essentials-part-8-retained-messages/)
set so that new connections get active Trip Modifications and Shapes published
to them on connect.

Deactivating a Trip Modification will be done by
[publishing a zero-byte payload](https://www.hivemq.com/blog/mqtt-essentials-part-8-retained-messages/#heading-how-to-delete-retained-messages-in-mqtt)
each topic within the `<prefix>/trip_modifications/#{id}/`
topic hierarchy, which will clear any retained messages and ensure that new
subscribers are not notified of these now deleted messages and existing
are made aware of the removal subscribers.

### Schema
We'll publish using JSON encoded versions of the GTFS-RT Messages to these topics.
The `payload` of the MQTT message will contain a JSONAPI compatible string
where the `data` key contains the GTFS-RT Message encoded as JSON.

`<prefix>/trip_modifications/#{id}/trip_modification`
```json5
{
"data": {
# <GTFS-RT Trip Modification Message as JSON>
}
"meta": {
# this field will be removed once we give users the ability to activate and
# deactivate detours themselves.
#
# Currently, this indicates that this message should not be published to
# applications outside of the MBTA, and is for internal testing and
# development only.
"is_draft?": boolean
}
}
```
`<prefix>/trip_modifications/#{id}/shape`
```json5
{
"data": {
# <GTFS-RT Shape Message as JSON>
}
}
```

### Subscriber Outcomes
With this Structure, _theoretically_, the only subscription that Transit Data
should need to make is to the following topics.
```
<env_prefix>/trip_modifications/+/trip_modification
<env_prefix>/trip_modifications/+/shape
```
OR, Using [wildcard topics](https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/#heading-avoid-subscribing-to-wildcards):
```
<env_prefix>/trip_modifications/+/+
<env_prefix>/trip_modifications/#
```

## Consequences

This topic hierarchy requires that Skate is ensuring that the open retained
messages on MQTT are synced with our own internal SOT of which
Trip Modifications are active.

0 comments on commit 3d9b684

Please sign in to comment.