|
15 | 15 |
|
16 | 16 | """ This module contains REST servlets to do with rooms: /rooms/<paths> """ |
17 | 17 | import logging |
| 18 | +from enum import Enum |
18 | 19 | import re |
19 | 20 | from typing import TYPE_CHECKING, Awaitable, Dict, List, Optional, Tuple |
20 | 21 | from urllib import parse as urlparse |
|
62 | 63 |
|
63 | 64 | logger = logging.getLogger(__name__) |
64 | 65 |
|
| 66 | + |
| 67 | +class _RoomSize(Enum): |
| 68 | + """ |
| 69 | + Enum to differentiate sizes of rooms. This is a pretty good aproximation |
| 70 | + about how hard it will be to get events in the room. We could also look at |
| 71 | + room "complexity". |
| 72 | + """ |
| 73 | + |
| 74 | + # This doesn't necessarily mean the room is a DM, just that there is a DM |
| 75 | + # amount of people there. |
| 76 | + DM_SIZE = "direct_message_size" |
| 77 | + SMALL = "small" |
| 78 | + SUBSTANTIAL = "substantial" |
| 79 | + LARGE = "large" |
| 80 | + |
| 81 | + def get_room_size_label_for_member_count(member_count: int): |
| 82 | + if member_count <= 2: |
| 83 | + return _RoomSize.DM_SIZE |
| 84 | + elif member_count < 100: |
| 85 | + return _RoomSize.SMALL |
| 86 | + elif member_count < 1000: |
| 87 | + return _RoomSize.SUBSTANTIAL |
| 88 | + else: |
| 89 | + return _RoomSize.LARGE |
| 90 | + |
| 91 | + |
65 | 92 | # This is an extra metric on top of `synapse_http_server_response_time_seconds` |
66 | 93 | # which times the same sort of thing but this one allows us to see values |
67 | 94 | # greater than 10s. We use a separate dedicated histogram with its own buckets |
|
70 | 97 | messsages_response_timer = Histogram( |
71 | 98 | "synapse_room_message_list_rest_servlet_response_time_seconds", |
72 | 99 | "sec", |
73 | | - [], |
| 100 | + # We have a label for room size so we can try to see a more realistic |
| 101 | + # picture of /messages response time for bigger rooms. We don't want the |
| 102 | + # tiny rooms that can always respond fast skewing our results when we're trying |
| 103 | + # to optimize the bigger cases. |
| 104 | + ["room_size"], |
74 | 105 | buckets=( |
75 | 106 | 0.005, |
76 | 107 | 0.01, |
@@ -591,10 +622,13 @@ def __init__(self, hs: "HomeServer"): |
591 | 622 | self.auth = hs.get_auth() |
592 | 623 | self.store = hs.get_datastores().main |
593 | 624 |
|
594 | | - @messsages_response_timer.time() |
595 | 625 | async def on_GET( |
596 | 626 | self, request: SynapseRequest, room_id: str |
597 | 627 | ) -> Tuple[int, JsonDict]: |
| 628 | + processing_start_time = self.clock.time_msec() |
| 629 | + # Fire and forget and hope that we get a result by the end. |
| 630 | + room_member_count_co = self.store.get_number_joined_users_in_room(room_id) |
| 631 | + |
598 | 632 | requester = await self.auth.get_user_by_req(request, allow_guest=True) |
599 | 633 | pagination_config = await PaginationConfig.from_request( |
600 | 634 | self.store, request, default_limit=10 |
@@ -625,6 +659,12 @@ async def on_GET( |
625 | 659 | event_filter=event_filter, |
626 | 660 | ) |
627 | 661 |
|
| 662 | + processing_end_time = self.clock.time_msec() |
| 663 | + room_member_count = await room_member_count_co |
| 664 | + messsages_response_timer.labels( |
| 665 | + room_size=_RoomSize.get_room_size_label_for_member_count(room_member_count) |
| 666 | + ).observe((processing_start_time - processing_end_time) / 1000) |
| 667 | + |
628 | 668 | return 200, msgs |
629 | 669 |
|
630 | 670 |
|
|
0 commit comments