Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Enable cancellation of GET /members and GET /state requests #12708

Merged
merged 6 commits into from
May 11, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/12708.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enable cancellation of `GET /rooms/$room_id/members`, `GET /rooms/$room_id/state` and `GET /rooms/$room_id/state/$event_type/*` requests.
4 changes: 3 additions & 1 deletion synapse/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ class SomeServlet(RestServlet):
async def on_GET(self, request: SynapseRequest) -> ...:
...
"""
if method.__name__ not in _cancellable_method_names:
if method.__name__ not in _cancellable_method_names and not any(
method.__name__.startswith(name) for name in _cancellable_method_names
):
Copy link
Contributor

Choose a reason for hiding this comment

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

For any string x, x.startswith(x). So I think this could be

    if not any(
        method.__name__.startswith(prefix) for prefix in _cancellable_method_names
    ):

but having written that out, I'm not sure if it's clearer.

Copy link
Contributor

Choose a reason for hiding this comment

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

Note to self: this is used later when we decorate on_GET_no_state_key.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My thinking was: the string-in-set test is much faster (O(len(str)) and would succeed for almost every method we would use the decorator on. The prefix test is a lot slower (O(n len(str))), since it has to trawl through the list, and only applies to on_GET_no_state_key.

Not that any of this matters, since it's all startup cost.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renaming name to prefix in the generator is a good idea though!

Copy link
Contributor

Choose a reason for hiding this comment

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

That's fair. Glad you agree on prefix; I was a bit confused by all the names flying around.

raise ValueError(
"@cancellable decorator can only be applied to servlet methods."
)
Expand Down
6 changes: 5 additions & 1 deletion synapse/rest/client/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
)
from synapse.api.filtering import Filter
from synapse.events.utils import format_event_for_client_v2
from synapse.http.server import HttpServer
from synapse.http.server import HttpServer, cancellable
from synapse.http.servlet import (
ResolveRoomIdMixin,
RestServlet,
Expand Down Expand Up @@ -143,6 +143,7 @@ def register(self, http_server: HttpServer) -> None:
self.__class__.__name__,
)

@cancellable
def on_GET_no_state_key(
self, request: SynapseRequest, room_id: str, event_type: str
) -> Awaitable[Tuple[int, JsonDict]]:
Expand All @@ -153,6 +154,7 @@ def on_PUT_no_state_key(
) -> Awaitable[Tuple[int, JsonDict]]:
return self.on_PUT(request, room_id, event_type, "")

@cancellable
async def on_GET(
self, request: SynapseRequest, room_id: str, event_type: str, state_key: str
) -> Tuple[int, JsonDict]:
Expand Down Expand Up @@ -481,6 +483,7 @@ def __init__(self, hs: "HomeServer"):
self.auth = hs.get_auth()
self.store = hs.get_datastores().main

@cancellable
Copy link
Contributor

Choose a reason for hiding this comment

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

Sanity check: why is this request cancellation-safe? (I assume it follows from all your other PRs?)

async def on_GET(
self, request: SynapseRequest, room_id: str
) -> Tuple[int, JsonDict]:
Expand Down Expand Up @@ -602,6 +605,7 @@ def __init__(self, hs: "HomeServer"):
self.message_handler = hs.get_message_handler()
self.auth = hs.get_auth()

@cancellable
async def on_GET(
Comment on lines +608 to 609
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly---is it easy to summarise why this is safe? I suppose the fact that we're doing a GET suggests that we'll only be reading data, not writing it... which sounds generally safer to cancel.(?)

self, request: SynapseRequest, room_id: str
) -> Tuple[int, List[JsonDict]]:
Expand Down