Add usecase specific section.

Add event type to the body
Add event id template variable
toger5/expiring-events-keep-alive
Timo 2 years ago
parent 53f618648d
commit 087c74ee88

@ -17,7 +17,7 @@ A generic way in which one can automate expirations is desired.
The described usecase is solved if we allow to send an event in advance The described usecase is solved if we allow to send an event in advance
to the homeserver but let the homeserver compute when its actually added to the to the homeserver but let the homeserver compute when its actually added to the
dag. DAG.
The condition for actually sending the delayed event would could be a timeout. The condition for actually sending the delayed event would could be a timeout.
## Proposal ## Proposal
@ -30,21 +30,28 @@ since any event that will be sent once expired can be defined.
We call those events `Futures`. We call those events `Futures`.
A new endpoint is introduced: A new endpoint is introduced:
`PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}/future` `PUT /_matrix/client/v3/rooms/{roomId}/send/future/{txnId}`
and
`PUT /_matrix/client/v3/rooms/{roomId}/state/{eventType}/{stateKey}/future`
It behaves exactly like the normal send endpoint except that that it allows It behaves exactly like the normal send endpoint except that that it allows
to send a list of event contents. The body looks as following: to send a list of event contents. The body looks as following:
```json ```json
{ {
"m.timeout": 10, "m.timeout": 10,
"m.send_on_timeout": {...sendEventBody}, "m.send_on_timeout": {
"content": sendEventBody0,
"m.send_on_action:${actionName}": {...sendEventBody}, "type": "m.room.message",
},
"m.send_on_action:${actionName}": {
"content": sendEventBody1,
"type": "m.room.message"
},
// optional // optional
"m.send_now": {...sendEventBody}, "m.send_now": {
"content": sendEventBody2,
"type": "m.room.message"
},
} }
``` ```
@ -59,75 +66,79 @@ This guarantees that all tokens will expire eventually.
The homeserver can set a limit to the timeout and return an error if the limit The homeserver can set a limit to the timeout and return an error if the limit
is exceeded. is exceeded.
### Response
The response will mimic the request: The response will mimic the request:
```json ```json
{ {
"m.send_on_timeout": { "m.send_on_timeout": {
"eventId": "id_hash" "eventId": "id_hash"
}, },
"m.send_on_action:${actionName}": { "m.send_on_action:${actionName}": {
"eventId": "id_hash" "eventId": "id_hash"
}, },
"future_token": "token", "future_token": "token",
// optional // optional
"m.send_now": { "eventId": "id_hash"}, "m.send_now": { "eventId": "id_hash" }
} }
``` ```
### Delegating futures
The `token` can be used to call another future related endpoint: The `token` can be used to call another future related endpoint:
`PUT /_matrix/client/v3/futures/refresh` and `PUT /_matrix/client/v3/futures/action/${actionName}`. `PUT /_matrix/client/v3/futures/refresh` and `PUT /_matrix/client/v3/futures/action/${actionName}`.
where the body is: where the body is:
```json ```json
{ {
"future_token":"token" "future_token": "token"
} }
``` ```
The information required to call this endpoint is very limited so that almost The information required to call this endpoint is very limited so that almost
no metadata is leaked. This allows to share a refresh link to a different no metadata is leaked. This allows to share a refresh link to a different
service (an SFU for instance) that can track the current client connection state, service. This allows to delegate the send time. An SFU for instance, that tracks the current client connection state,
and pings the HS to refresh and call a dedicated action to communicate and pings the HS to refresh and call a dedicated action to communicate
that the user has intentionally left the conference. that the user has intentionally left the conference.
The homeserver does the following when receiving a Future. The homeserver does the following when receiving a Future.
- It sends the optional `m.send_now` event. - It **sends** the optional `m.send_now` event.
- It generates a `future_token` and stores it alongside with the time - It **generates** a `future_token` and stores it alongside with the time
of retrieval, the event list and the timeout duration. of retrieval, the event list and the timeout duration.
- Starts a timer for the stored `future_token`. - **Starts a timer** for the stored `future_token`.
- If a `PUT /_matrix/client/v3/futures/refresh` is received, the
timer is restarted with the stored timeout duration. - If a `PUT /_matrix/client/v3/futures/refresh` is received, it
- If a `PUT /_matrix/client/v3/futures/action/${actionName}` is received, one of **restarts the timer** with the stored timeout duration.
the associated `m.action:${actionName}` - If a `PUT /_matrix/client/v3/futures/action/${actionName}` is received, it **sends the associated action event**
event will be send. `m.action:${actionName}`.
- If the timer times out, the one of the `m.send_timeout` event will be sent. - If the timer times out, **it sends the timeout event** `m.send_timeout`.
- If the future - If the future is a state event and includes a `m.send_now` event
- is a state event (`PUT /_matrix/client/v3/rooms/{roomId}/state/{eventType}/{stateKey}/future`)
- and includes a `m.send_now` event
the future is only valid while the `m.send_now` the future is only valid while the `m.send_now`
is still the current state. This means, if the homeserver receives is still the current state:
a new state event for the same state key, the `future_token`
gets invalidated and the associated timer is stopped. - This means, if the homeserver receives
a new state event for the same state key, the **`future_token`**
**gets invalidated and the associated timer is stopped**.
- There is no race condition here since a possible race between timeout and - There is no race condition here since a possible race between timeout and
new event will always converge to the new event: new event will always converge to the new event:
- Timeout -> new event: the room state will be updated twice. once by - Timeout -> new event: the room state will be updated twice. once by
the content of the `m.send_on_timeout` event but later with the new event. the content of the `m.send_on_timeout` event but later with the new event.
- new event -> timeout: the new event will invalidate the future. No - new event -> timeout: the new event will invalidate the future. No
- When a timeout or action future is sent, the homeserver stops the associated
timer and invalidates (deletes) the `future_token`. - After the homeservers sends a timeout or action future event, the associated
timer and `future_token` is canceled/invalidated.
So for each Future the client sends, the homeserver will send one event So for each Future the client sends, the homeserver will send one event
conditionally at an unknown time that can trigger logic on the client. conditionally at an unknown time that can trigger logic on the client.
This allows for any generic timeout logic. This allows for any generic timeout logic.
Timed messages/reminders or ephemeral events could be implemented using this where Timed messages/reminders or ephemeral events could be implemented using this where
clients send a redact as a future or a room event with intentional mentions. clients send a redact as a future or a room event with intentional mentions.
In some scenarios it is important to allow to send an event with an associated In some scenarios it is important to allow to send an event with an associated
future at the same time. future at the same time.
@ -143,6 +154,78 @@ future at the same time.
For this usecase an optional `m.send_now` field can be added to the body. For this usecase an optional `m.send_now` field can be added to the body.
## Usecase specific considerations
### MatrixRTC
We want can use the actions and the timeout for matrix rtc for the following situations
- If the client takes care of its membership, we use a short timeout value (around 5-20 seconds)
The client will have to ping the refresh endpoint approx every 2-19 seconds.
- When the SFU is capable of taking care of managing our connection state and we trust the SFU to
not disconnect a really long value can be chosen (approx. 2-10hours). The SFU will then only send
an action once the user disconnects or looses connection (it could even be a different action for both cases
handling them differently on the client)
This significantly reduces the amount of calls for the `/future` endpoint since the sfu only needs to ping
once per session (per user) and every 2-5hours (instead of every `X` seconds.)
### Self destructing messages
This MSC also allows to implement self destructing messages:
`PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}`
```json
{
"m.text": "my msg"
}
```
`PUT /_matrix/client/v3/rooms/{roomId}/send/future/{txnId}`
```json
{
"m.timeout": 10*60,
"m.send_on_timeout": {
"type":"m.room.readact",
"content":{
"redacts": "EvId"
}
}
}
```
## EventId template variable
It would be useful to be able to send redactions and edits as one http request.
This would make sure that the client cannot loose connection after sending the first event.
For instance sending a self destructing message without the redaction.
The optional proposal is to introduce template variables that are only valid in `Future` events.
`$m.send_now.event_id` in the content of one of the `m.send_on_action:${actionName}` and
`m.send_on_timeout` contents this template variable can be used.
The **Self destructing messages** example would simplify to:
`PUT /_matrix/client/v3/rooms/{roomId}/send/future/{txnId}`
```json
{
"m.send_now":{
"type":"m.room.message",
"content":{
"m.text": "my msg"
}
},
"m.timeout": 10*60,
"m.send_on_timeout": {
"type":"m.room.readact",
"content":{
"redacts": "$m.send_now.event_id"
}
}
}
```
## Potential issues ## Potential issues
## Alternatives ## Alternatives
@ -181,4 +264,3 @@ even tell with which room or user it is interacting.
## Unstable prefix ## Unstable prefix
## Dependencies ## Dependencies

Loading…
Cancel
Save