- 
                Notifications
    
You must be signed in to change notification settings  - Fork 415
 
MSC4140: Cancellable delayed events #4140
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
480b00a
              8839b8d
              8bf6db7
              8ec6374
              9f45cfa
              54fff99
              abdfe1c
              53f6186
              087c74e
              538b853
              f7a1aad
              f5f4b38
              c16afbc
              c52c80d
              bf22260
              7f0d80f
              7b192ac
              f3bf66d
              2d7b27d
              1140ce9
              0a7896e
              8fa33d6
              49d5294
              7550d9b
              a663bb4
              99b3a20
              eb50a19
              9ff051e
              425b9bf
              2e7be46
              5653fe1
              af060cf
              bff704c
              fa461e2
              d195218
              b5ac9b2
              c07dd9b
              b79e4e2
              e125901
              0443cd9
              7df0919
              ff95144
              93c932a
              6cce3bd
              ac2d2c5
              84e20fd
              ac3bd9d
              de77a90
              677d6f3
              4caecd1
              c482d58
              9098fea
              7e06e85
              a1b8121
              3a3a5b5
              97d4141
              99c9467
              6f2aa5e
              5e43db0
              84b8dc0
              e7d0986
              850bf9e
              e1b460a
              114da1e
              772590f
              4a2ca48
              37979cd
              195ab6a
              0f8a2d1
              886f378
              8523ed4
              883e6b5
              caece4d
              28970ec
              2f57b0b
              9d5c93a
              da3d75e
              f7e4e9b
              b8e317f
              b499995
              8dc05a4
              0a777f4
              a09a883
              72a808e
              d1a37f0
              3358138
              904e3d6
              c25e5a3
              96f9063
              99b79ba
              dc5fd93
              bf5df9b
              2f53661
              fd94c18
              e532e93
              0d7821a
              64f6dfc
              ba78cde
              c2587fe
              1036165
              2afcebb
              8c5b612
              6afd0f3
              1359f2b
              59392f2
              f167eb4
              3efecea
              4bb8929
              24d1c7d
              2f4a73a
              33af637
              76d015a
              cdcddd2
              d6c065e
              0a18141
              a53f83f
              eb0a504
              9db8058
              c19a394
              e2af939
              061dd56
              79aeaf5
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -83,6 +83,8 @@ Content-Type: application/json | |
| ``` | ||
| 
     | 
||
| The `delay_id` is an [opaque identifier](https://spec.matrix.org/v1.16/appendices/#opaque-identifiers) generated by the server. | ||
| It MUST be globally unique and SHOULD be as difficult to guess/craft as an access token, so that knowledge of a `delay_id` may | ||
| securely grant control of it via [the management endpoint](#managing-delayed-events). | ||
| 
     | 
||
| The server MAY round the delay up to a maximum of 30 seconds away from the request. | ||
| 
     | 
||
| 
          
            
          
           | 
    @@ -120,29 +122,30 @@ Content-Type: application/json | |
| 
     | 
||
| ### Managing delayed events | ||
| 
     | 
||
| A new authenticated client-server API endpoint at `POST /_matrix/client/v1/delayed_events/{delay_id}` allows scheduled events | ||
| A set of new unauthenticated client-server API endpoints at `POST /_matrix/client/v1/delayed_events/{delay_id}/[send|cancel|restart]` allows scheduled events | ||
| to be managed. | ||
| 
     | 
||
| The body of the request is a JSON object containing the following fields: | ||
| The final path component of these endpoints specifies the action to take on the delayed event: | ||
| 
     | 
||
| - `action` - The action to take on the delayed event.\ | ||
| Must be one of: | ||
| - `send` - Send the delayed event immediately instead of waiting for the delay time to be reached. | ||
| - `cancel` - Cancel the delayed event so that it is never sent. | ||
| - `restart` - Reset the send time to be `now + original_delay`. | ||
| - `send` - Send the delayed event immediately instead of waiting for the delay time to be reached. | ||
| - `cancel` - Cancel the delayed event so that it is never sent. | ||
| - `restart` - Reset the send time to be `now + original_delay`. | ||
| 
     | 
||
| For example, the following would send the delayed event with delay ID `1234567890` immediately: | ||
| 
     | 
||
| ```http | ||
| POST /_matrix/client/v1/delayed_events/1234567890 | ||
| POST /_matrix/client/v1/delayed_events/1234567890/send | ||
| Content-Type: application/json | ||
| 
     | 
||
| { | ||
| "action": "send" | ||
| } | ||
| ``` | ||
| 
     | 
||
| Where the `action` is `send`, the homeserver **should** apply rate limiting to provide mitigation against the | ||
| These endpoints are unauthenticated so that control over a particular delayed event may be | ||
| [delegated to an external service](#delegating-delayed-events) | ||
| by sharing the target delayed event's `delay_id` with the service. | ||
| 
     | 
||
| Where the action is `send`, the homeserver **should** apply rate limiting to provide mitigation against the | ||
| [High Volume of Messages](https://spec.matrix.org/v1.16/appendices/#threat-high-volume-of-messages) threat. | ||
| 
     | 
||
| The server will respond with HTTP 404 and an `M_NOT_FOUND` error if the `delay_id` is not recognized or was already cancelled. | ||
| 
        
          
        
         | 
    @@ -159,6 +162,27 @@ that happened while sending the event (e.g. HTTP 403 and `M_FORBIDDEN` if the us | |
| The primary point of rate limiting is event sending when the delay times out or the event is sent using the `send` | ||
| action. However, servers can choose to rate limit the management endpoints themselves as well if necessary. | ||
| 
     | 
||
| #### Delegating delayed events | ||
| 
     | 
||
| It is useful for external services to also interact with delayed events. If a client disconnects, an external service can | ||
| be the best source to send the delayed event/"last will". | ||
| 
     | 
||
| To permit this, the `delay_id` that uniquely identifies a delayed event also behaves as a scoped access token | ||
| that only allows to interact with the `POST /delayed_events` endpoints on that specific `delay_id`. | ||
| 
     | 
||
| With this, an SFU that tracks the current client connection state could be given the power to control the delayed event. | ||
| The client would share the `delay_id` and the required details, so that the SFU can call the | ||
| `POST /delayed_events/{delay_id}/refresh` endpoint while a user is connected | ||
| and can call the `POST /delayed_events/{delay_id}/send` endpoint once the user disconnects. | ||
| This way, the SFU can be used as the source of truth for the call membership events without knowing anything about | ||
| the Matrix call. | ||
| 
     | 
||
| Since the SFU has a much lower chance of running into a network issue, | ||
| `POST /delayed_events/{delay_id}/restart` calls may be sent much more infrequently. | ||
| Instead of calling that endpoint every couple of seconds, a delayed event's | ||
| timeout can be set to be long (e.g. 6 hours), as the SFU can be expected to not forget sending the `POST /delayed_events/{delay_id}/send` requests | ||
| when it detects a disconnecting client. | ||
| 
     | 
||
| ### Getting delayed events | ||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a poll mechanism. In my opinion, we would need a push (sync) mechanism to take really advantage of this MSC and be able to introduce a bunch of new Matrix features based on it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the above. The current MSC only ever exposes the scheduled delayed events to the sender. This might be worth explicitly mentioning in the MSC. I hope this approach makes sense and coveres all of the usecases you have in mind? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't expect to share  The other problem I see is, that the MSC suggest a new endpoint for getting  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a follow up MSC to include it in sync (sorry that i confused user vs room delayed events sharing) The reason was to make this msc simpler. It does only include finalized delayed events. So your point of syncing schedules to all devices via a push semantic is very valid. What do you think about moving/discussing this functionality to the other MSC? (It sadly is still in draft)  | 
||
| 
     | 
||
| The new authenticated client-server API endpoint `GET /_matrix/client/v1/delayed_events` allows clients to get a list of | ||
| 
          
            
          
           | 
    @@ -391,11 +415,10 @@ the call membership "alive". | |
| For example it could make the request every 5 seconds (or some other period less than the `delay`): | ||
| 
     | 
||
| ```http | ||
| POST /_matrix/client/v1/delayed_events/1234567890 | ||
| POST /_matrix/client/v1/delayed_events/1234567890/restart | ||
| Content-Type: application/json | ||
| 
     | 
||
| { | ||
| "action": "restart" | ||
| } | ||
| ``` | ||
| 
     | 
||
| 
          
            
          
           | 
    @@ -462,28 +485,20 @@ it would make it transparent to clients, when an event was scheduled and when it | |
| 
     | 
||
| ## Alternatives | ||
                
      
                  hughns marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||
| 
     | 
||
| ### Delegating delayed events | ||
| 
     | 
||
| It is useful for external services to also interact with delayed events. If a client disconnects, an external service can | ||
| be the best source to send the delayed event/"last will". | ||
| ### OAuth 2.0 scope for management endpoints | ||
| 
     | 
||
| This is not covered in this MSC but could be realized with scoped access tokens. | ||
| A scoped token that only allows to interact with the `delayed_events` endpoint and only with a subset of `delay_id`s | ||
| would be used. | ||
| Instead of the [delayed event management endpoints](#managing-delayed-events) being unauthenticated | ||
| to permit [delegation to an external service](#delegating-delayed-events), | ||
| those endpoints could be given an OAuth 2.0 scope and be restricted to sessions that have requested it. | ||
| The scope would be within the existing `urn:matrix:client:api:*` scope, | ||
| so that access to the entirety the Client-Server API would include access to these endpoints as well. | ||
| 
     | 
||
| With this, an SFU that tracks the current client connection state could be given the power to control the delayed event. | ||
| The client would share the scoped token and the required details, so that the SFU can call the | ||
| `refresh` endpoint while a user is connected | ||
| and can call the delayed event `send` request once the user disconnects | ||
| (using a `{"action": "restart"}` and a `{"action": "send"}` `/delayed_events` request.). | ||
| This way, the SFU can be used as the source of truth for the call membership events without knowing anything about | ||
| the Matrix call. | ||
| Using OAuth 2.0 to restrict access on these endpoints has many benefits over using a path parameter (`delay_id`) as an access token, | ||
| such as more fine-grained revocability on access to the endpoints, | ||
| and better identification of what entity is requesting these endpoints, which can be used to apply per-entity ratelimits. | ||
| 
     | 
||
| Since the SFU has a much lower chance of running into a network issue, | ||
| `{"action": "restart"}` calls may be sent much more infrequently. | ||
| Instead of calling the `/delayed_events` endpoint every couple of seconds, a delayed event's | ||
| timeout can be set to be long (e.g. 6 hours), as the SFU can be expected to not forget sending the `{"action": "send"}` action | ||
| when it detects a disconnecting client. | ||
| The downsides of this approach are its requirement on the homeserver supporting the OAuth 2.0 login API, | ||
| and the additional network/configuration overhead for external services to request access to this scope. | ||
| 
     | 
||
| ### Batch sending | ||
| 
     | 
||
| 
          
            
          
           | 
    @@ -539,7 +554,7 @@ an indicator to determine if the event is expired, instead of letting the SFU | |
| inform about the call termination or using the call app ping/refresh loop as proposed earlier in this MSC. | ||
| 
     | 
||
| The advantage is that this does not require introducing a new ping system | ||
| (as is proposed here by using the `delayed_events` restart action). | ||
| (as is proposed here by using the `delayed_events/{delay_id}/restart` action). | ||
| Though with cryptographic identities, the client needs to create the leave event. | ||
| 
     | 
||
| The timeout for syncs are much slower than what would be desirable (30s vs 5s). | ||
| 
          
            
          
           | 
    ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rough implementation at https://github.com/element-hq/synapse/compare/hs/delayed-event-anonymous?expand=1