14
14
# limitations under the License.
15
15
16
16
import logging
17
- from typing import Dict , List , Optional
17
+ from typing import Dict , List , Optional , Union
18
18
19
19
from prometheus_client import Counter
20
20
30
30
event_processing_loop_counter ,
31
31
event_processing_loop_room_count ,
32
32
)
33
- from synapse .metrics .background_process_metrics import run_as_background_process
33
+ from synapse .metrics .background_process_metrics import (
34
+ run_as_background_process ,
35
+ wrap_as_background_process ,
36
+ )
34
37
from synapse .types import Collection , JsonDict , RoomStreamToken , UserID
35
38
from synapse .util .metrics import Measure
36
39
@@ -53,7 +56,7 @@ def __init__(self, hs):
53
56
self .current_max = 0
54
57
self .is_processing = False
55
58
56
- async def notify_interested_services (self , max_token : RoomStreamToken ):
59
+ def notify_interested_services (self , max_token : RoomStreamToken ):
57
60
"""Notifies (pushes) all application services interested in this event.
58
61
59
62
Pushing is done asynchronously, so this method won't block for any
@@ -72,6 +75,12 @@ async def notify_interested_services(self, max_token: RoomStreamToken):
72
75
if self .is_processing :
73
76
return
74
77
78
+ # We only start a new background process if necessary rather than
79
+ # optimistically (to cut down on overhead).
80
+ self ._notify_interested_services (max_token )
81
+
82
+ @wrap_as_background_process ("notify_interested_services" )
83
+ async def _notify_interested_services (self , max_token : RoomStreamToken ):
75
84
with Measure (self .clock , "notify_interested_services" ):
76
85
self .is_processing = True
77
86
try :
@@ -166,8 +175,11 @@ async def handle_room_events(events):
166
175
finally :
167
176
self .is_processing = False
168
177
169
- async def notify_interested_services_ephemeral (
170
- self , stream_key : str , new_token : Optional [int ], users : Collection [UserID ] = [],
178
+ def notify_interested_services_ephemeral (
179
+ self ,
180
+ stream_key : str ,
181
+ new_token : Optional [int ],
182
+ users : Collection [Union [str , UserID ]] = [],
171
183
):
172
184
"""This is called by the notifier in the background
173
185
when a ephemeral event handled by the homeserver.
@@ -183,13 +195,34 @@ async def notify_interested_services_ephemeral(
183
195
new_token: The latest stream token
184
196
users: The user(s) involved with the event.
185
197
"""
198
+ if not self .notify_appservices :
199
+ return
200
+
201
+ if stream_key not in ("typing_key" , "receipt_key" , "presence_key" ):
202
+ return
203
+
186
204
services = [
187
205
service
188
206
for service in self .store .get_app_services ()
189
207
if service .supports_ephemeral
190
208
]
191
- if not services or not self . notify_appservices :
209
+ if not services :
192
210
return
211
+
212
+ # We only start a new background process if necessary rather than
213
+ # optimistically (to cut down on overhead).
214
+ self ._notify_interested_services_ephemeral (
215
+ services , stream_key , new_token , users
216
+ )
217
+
218
+ @wrap_as_background_process ("notify_interested_services_ephemeral" )
219
+ async def _notify_interested_services_ephemeral (
220
+ self ,
221
+ services : List [ApplicationService ],
222
+ stream_key : str ,
223
+ new_token : Optional [int ],
224
+ users : Collection [Union [str , UserID ]],
225
+ ):
193
226
logger .info ("Checking interested services for %s" % (stream_key ))
194
227
with Measure (self .clock , "notify_interested_services_ephemeral" ):
195
228
for service in services :
@@ -237,14 +270,17 @@ async def _handle_receipts(self, service: ApplicationService):
237
270
return receipts
238
271
239
272
async def _handle_presence (
240
- self , service : ApplicationService , users : Collection [UserID ]
273
+ self , service : ApplicationService , users : Collection [Union [ str , UserID ] ]
241
274
):
242
275
events = [] # type: List[JsonDict]
243
276
presence_source = self .event_sources .sources ["presence" ]
244
277
from_key = await self .store .get_type_stream_id_for_appservice (
245
278
service , "presence"
246
279
)
247
280
for user in users :
281
+ if isinstance (user , str ):
282
+ user = UserID .from_string (user )
283
+
248
284
interested = await service .is_interested_in_presence (user , self .store )
249
285
if not interested :
250
286
continue
0 commit comments