|
92 | 92 | category="synapse-reactor-clock",
|
93 | 93 | )
|
94 | 94 |
|
| 95 | +MULTIPLE_INTERNAL_CLOCKS_CREATED = ErrorCode( |
| 96 | + "multiple-internal-clocks", |
| 97 | + "Only one instance of `clock.Clock` should be created", |
| 98 | + category="synapse-reactor-clock", |
| 99 | +) |
| 100 | + |
95 | 101 |
|
96 | 102 | class Sentinel(enum.Enum):
|
97 | 103 | # defining a sentinel in this way allows mypy to correctly handle the
|
@@ -237,6 +243,9 @@ def get_function_signature_hook(
|
237 | 243 | if fullname == "twisted.internet.task.LoopingCall":
|
238 | 244 | return check_looping_call
|
239 | 245 |
|
| 246 | + if fullname == "synapse.util.clock.Clock": |
| 247 | + return check_clock_creation |
| 248 | + |
240 | 249 | return None
|
241 | 250 |
|
242 | 251 | def get_method_signature_hook(
|
@@ -331,6 +340,25 @@ def check_looping_call(ctx: FunctionSigContext) -> CallableType:
|
331 | 340 | return signature
|
332 | 341 |
|
333 | 342 |
|
| 343 | +def check_clock_creation(ctx: FunctionSigContext) -> CallableType: |
| 344 | + """ |
| 345 | + Ensure that the only `clock.Clock` is the one used by the `HomeServer`. |
| 346 | +
|
| 347 | + Args: |
| 348 | + ctx: The `FunctionSigContext` from mypy. |
| 349 | + """ |
| 350 | + signature: CallableType = ctx.default_signature |
| 351 | + ctx.api.fail( |
| 352 | + "Expected the only `clock.Clock` instance to be the one used by the `HomeServer`. " |
| 353 | + "This is so that the `HomeServer` can cancel any tracked delayed or looping calls " |
| 354 | + "during server shutdown", |
| 355 | + ctx.context, |
| 356 | + code=MULTIPLE_INTERNAL_CLOCKS_CREATED, |
| 357 | + ) |
| 358 | + |
| 359 | + return signature |
| 360 | + |
| 361 | + |
334 | 362 | def check_call_when_running(ctx: MethodSigContext) -> CallableType:
|
335 | 363 | """
|
336 | 364 | Ensure that the `reactor.callWhenRunning` callsites aren't used.
|
|
0 commit comments