Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSC4140: Cancellable delayed events #4140

Open
wants to merge 73 commits into
base: main
Choose a base branch
from

Conversation

toger5 added 2 commits May 7, 2024 18:52
Signed-off-by: Timo K <toger5@hotmail.de>
Signed-off-by: Timo K <toger5@hotmail.de>
@toger5 toger5 force-pushed the toger5/expiring-events-keep-alive branch from 2bc07c4 to 0eb1abc Compare May 7, 2024 17:03
Signed-off-by: Timo K <toger5@hotmail.de>
@toger5 toger5 force-pushed the toger5/expiring-events-keep-alive branch from 0eb1abc to 8bf6db7 Compare May 8, 2024 15:49
Signed-off-by: Timo K <toger5@hotmail.de>
Signed-off-by: Timo K <toger5@hotmail.de>
@turt2live turt2live changed the title Draft for expiring event PR MSC4140: Expiring events with keep alive endpoint May 9, 2024
@turt2live turt2live added proposal A matrix spec change proposal client-server Client-Server API kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. labels May 9, 2024
@toger5 toger5 force-pushed the toger5/expiring-events-keep-alive branch from 3e54c2a to c82adf7 Compare May 10, 2024 17:54
Signed-off-by: Timo K <toger5@hotmail.de>
@toger5 toger5 force-pushed the toger5/expiring-events-keep-alive branch from c82adf7 to 54fff99 Compare May 10, 2024 18:08
…is used to trigger on of the actions

Signed-off-by: Timo K <toger5@hotmail.de>
Signed-off-by: Timo K <toger5@hotmail.de>
Add event type to the body
Add event id template variable
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
proposals/4140-delayed-events-futures.md Outdated Show resolved Hide resolved
toger5 and others added 2 commits May 31, 2024 09:20
Co-authored-by: Andrew Ferrazzutti <af_0_af@hotmail.com>
of this proposal.

The proposal here allows a Matrix client to schedule a "hangup" state event to be sent after a specified time period.
The client can then periodically restarts the timer whilst it is running. If the client is no longer running or able
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The client can then periodically restarts the timer whilst it is running. If the client is no longer running or able
The client can then periodically restart the timer whilst it is running. If the client is no longer running or able


- Update the room state every x seconds.
This allows clients to check how long an event has not been updated and ignore it if it's expired.
- Use Future events with a 10s timeout to send the disconnected from call
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

references to futures & /update_future are presumably stale now?

A limit on the maximum number of delayed events that can be outstanding at one time could also provide some mitigation against
this attack.

## Use case specific considerations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feature could also be useful for temporary mutes/bans/kicks, temporary invites, etc.

This reverts commit 772590f.
Clients should keep track of transaction IDs themselves.
Comment on lines +262 to +275
#### Delayed state events are cancelled by a more recent state event

If a new state event is sent to the same room with the same (event type, state key) pair as a delayed event, the delayed
event is cancelled.

There is no race condition here since a possible race between timeout and the _new state event_ will always converge to
the _new state event_:

- timeout for _delayed event_ followed by _new state event_: the room state will be updated twice: once by the content of
the delayed event but later with the content of _new state event_.
- _new state event_ followed by timeout for _delayed event_: the _new state event_ will cancel the outstanding _delayed event_.

Note that this behaviour does not apply to regular (non-state) events as there is no concept of a `(type, state_key)`
pair that could be overwritten.
Copy link
Author

@toger5 toger5 Sep 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might not be the best way to treat this. Here are my reasons why:

  • It is very easy to emulate this behavior by just cancelling the delayed event before sending a new state event.
  • In the matrixRTC spec I would like to argue that the order should be: send the delayed leave event FIRST and afterwards the active membership event. This guarantees that only expiring call memberships will be sent.
  • I would like to replace this section with:
Suggested change
#### Delayed state events are cancelled by a more recent state event
If a new state event is sent to the same room with the same (event type, state key) pair as a delayed event, the delayed
event is cancelled.
There is no race condition here since a possible race between timeout and the _new state event_ will always converge to
the _new state event_:
- timeout for _delayed event_ followed by _new state event_: the room state will be updated twice: once by the content of
the delayed event but later with the content of _new state event_.
- _new state event_ followed by timeout for _delayed event_: the _new state event_ will cancel the outstanding _delayed event_.
Note that this behaviour does not apply to regular (non-state) events as there is no concept of a `(type, state_key)`
pair that could be overwritten.
#### State which is effected by delayed events will be marked in the unsigned field
If a state event is sent for a state key where there is already a delayed event scheduled the homeserver will add a:
`has_delayed_overwrite: true` property to the unsigned section of the state event.
This is not required if the delayed event is received after a normal state event.
This allows client to check if a state event is temporal: `has_delayed_overwrite: true`.
`m.call.member` events for instance will only be valid if they are temporal (It allows the receiving clients to evaluate if the sending client did not forget to schedule the delayed leave event.)
The `has_delayed_overwrite: true` unsigned property is also added to delayed state events that timeout or are send into the DAG while there is another delayed event scheduled for the same state key.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • It is very easy to emulate this behavior by just cancelling the delayed event before sending a new state event.

This isn't true for state that can be set by other users, who don't have the option to cancel (or even know about) delayed state from someone else.

  • In the matrixRTC spec I would like to argue that the order should be: send the delayed leave event FIRST and afterwards the active membership event. This guarantees that only expiring call memberships will be sent.

This is a good idea, but I believe it will work regardless of what the behaviour is for overwritten delayed state.

Comment on lines +190 to +192
The endpoint accepts a query parameter `from` which is a token that can be used to paginate the list of delayed events as
per the [pagination convention](https://spec.matrix.org/v1.11/appendices/#pagination). The homeserver can choose a suitable
page size.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also define how the response should order the returned delayed events, lest the paginated results are jumbled & difficult to navigate through.

I propose sorting in order of increasing send time, i.e. running_since + delay.

@AndrewFerr
Copy link
Member

As suggested during a review of Complement tests, this MSC should specify what happens when a user leaves a room they have pending delayed messages for.

The most "unexpected" thing to do is to cancel all delayed events for a room when leaving it.

On the other hand, not cancelling them is an option as well:

  • If the user rejoins a room they had left, any of their still-pending delayed messages for that room will end up getting sent
  • If the user is not in a room by the time any of their delayed messages for that room are to be sent, the event sending will simply fail with a 400-class error

The latter is in the same vein as evaluating power levels at the point of sending.

Note that the Synapse implementation does not cancel delayed events for left rooms.

Comment on lines +255 to +256
Power levels are evaluated for each event only once the delay has occurred and it will be distributed/inserted into the
DAG. This implies a delayed event can fail if it violates power levels at the time the delay passes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should users be notified of delayed events that hit power level failures (or any 400-class error) upon being sent?

If so, perhaps delayed event send failures can be included in /sync responses, for clients to handle however they like.

If not, then this spec should make it explicit that delayed event send failures are effectively unhandled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client-server Client-Server API kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal A matrix spec change proposal
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants