Skip to content

Commit b97b2dd

Browse files
committed
Debug: Eliminate variables
Reproduction: 1. `poetry run synapse_homeserver --config-path homeserver.yaml` 1. Ctrl + C to stop the server 1. Notice `LoggingContext: Expected logging context main was lost` in the logs
1 parent 0a865fd commit b97b2dd

File tree

5 files changed

+175
-36
lines changed

5 files changed

+175
-36
lines changed

synapse/handlers/federation.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ def __init__(self, hs: "HomeServer"):
188188
# were shut down.
189189
if not hs.config.worker.worker_app:
190190
run_as_background_process(
191-
"resume_sync_partial_state_room",
191+
# "resume_sync_partial_state_room",
192+
"rspsr",
192193
self.server_name,
193194
self._resume_partial_state_room_sync,
194195
)
@@ -1788,15 +1789,17 @@ async def get_room_complexity(
17881789

17891790
async def _resume_partial_state_room_sync(self) -> None:
17901791
"""Resumes resyncing of all partial-state rooms after a restart."""
1792+
logger.info("asdf->_resume_partial_state_room_sync")
17911793
assert not self.config.worker.worker_app
17921794

17931795
partial_state_rooms = await self.store.get_partial_state_room_resync_info()
1794-
for room_id, resync_info in partial_state_rooms.items():
1795-
self._start_partial_state_room_sync(
1796-
initial_destination=resync_info.joined_via,
1797-
other_destinations=resync_info.servers_in_room,
1798-
room_id=room_id,
1799-
)
1796+
# for room_id, resync_info in partial_state_rooms.items():
1797+
# self._start_partial_state_room_sync(
1798+
# initial_destination=resync_info.joined_via,
1799+
# other_destinations=resync_info.servers_in_room,
1800+
# room_id=room_id,
1801+
# )
1802+
logger.info("asdf->_resume_partial_state_room_sync done")
18001803

18011804
def _start_partial_state_room_sync(
18021805
self,

synapse/logging/context.py

Lines changed: 137 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
overload,
5050
)
5151

52+
import secrets
53+
import string
5254
import attr
5355
from typing_extensions import ParamSpec
5456
from traceback import format_stack
@@ -386,6 +388,10 @@ def __enter__(self) -> "LoggingContext":
386388
self.previous_context,
387389
format_stack()[-2]
388390
.replace("/home/eric/Documents/github/element/synapse/", "")
391+
.replace(
392+
"/home/eric/.cache/pypoetry/virtualenvs/matrix-synapse-xCtC9ulO-py3.13/lib/",
393+
"",
394+
)
389395
.replace("\n", "->"),
390396
)
391397
old_context = set_current_context(self)
@@ -416,6 +422,10 @@ def __exit__(
416422
self.previous_context,
417423
format_stack()[-2]
418424
.replace("/home/eric/Documents/github/element/synapse/", "")
425+
.replace(
426+
"/home/eric/.cache/pypoetry/virtualenvs/matrix-synapse-xCtC9ulO-py3.13/lib/",
427+
"",
428+
)
419429
.replace("\n", "->"),
420430
)
421431
current = set_current_context(self.previous_context)
@@ -635,25 +645,39 @@ def filter(self, record: logging.LogRecord) -> Literal[True]:
635645
return True
636646

637647

648+
def random_string(length: int) -> str:
649+
"""Generate a cryptographically secure string of random letters.
650+
651+
Drawn from the characters: `a-z` and `A-Z`
652+
"""
653+
return "".join(secrets.choice(string.ascii_letters) for _ in range(length))
654+
655+
638656
class PreserveLoggingContext:
639657
"""Context manager which replaces the logging context
640658
641659
The previous logging context is restored on exit."""
642660

643-
__slots__ = ["_old_context", "_new_context"]
661+
__slots__ = ["_old_context", "_new_context", "_instance_id"]
644662

645663
def __init__(
646664
self, new_context: LoggingContextOrSentinel = SENTINEL_CONTEXT
647665
) -> None:
648666
self._new_context = new_context
667+
self._instance_id = random_string(5)
649668

650669
def __enter__(self) -> None:
651670
logger.debug(
652-
"PreserveLoggingContext(%s) enter (old_context=%s) (source: %s)",
671+
"PreserveLoggingContext(%s) %s enter (old_context=%s) (source: %s)",
653672
self._new_context,
673+
self._instance_id,
654674
current_context(),
655675
format_stack()[-2]
656676
.replace("/home/eric/Documents/github/element/synapse/", "")
677+
.replace(
678+
"/home/eric/.cache/pypoetry/virtualenvs/matrix-synapse-xCtC9ulO-py3.13/lib/",
679+
"",
680+
)
657681
.replace("\n", "->"),
658682
)
659683
self._old_context = set_current_context(self._new_context)
@@ -665,11 +689,16 @@ def __exit__(
665689
traceback: Optional[TracebackType],
666690
) -> None:
667691
logger.debug(
668-
"PreserveLoggingContext(%s) exit returning to old_context=%s (source: %s)",
692+
"PreserveLoggingContext(%s) %s exit returning to old_context=%s (source: %s)",
669693
self._new_context,
694+
self._instance_id,
670695
self._old_context,
671696
format_stack()[-2]
672697
.replace("/home/eric/Documents/github/element/synapse/", "")
698+
.replace(
699+
"/home/eric/.cache/pypoetry/virtualenvs/matrix-synapse-xCtC9ulO-py3.13/lib/",
700+
"",
701+
)
673702
.replace("\n", "->"),
674703
)
675704
context = set_current_context(self._old_context)
@@ -715,7 +744,16 @@ def set_current_context(context: LoggingContextOrSentinel) -> LoggingContextOrSe
715744
current = current_context()
716745

717746
logger.debug(
718-
"set_current_context(%s) old_context=%s - %s", context, current, format_stack()
747+
"| set_current_context(%s) old_context=%s - %s",
748+
context,
749+
current,
750+
[
751+
x.replace("/home/eric/Documents/github/element/synapse/", "").replace(
752+
"/home/eric/.cache/pypoetry/virtualenvs/matrix-synapse-xCtC9ulO-py3.13/lib/",
753+
"",
754+
)
755+
for x in format_stack()
756+
],
719757
)
720758

721759
if current is not context:
@@ -837,7 +875,25 @@ def run_in_background(
837875
CRITICAL error about an unhandled error will be logged without much
838876
indication about where it came from.
839877
"""
878+
instance_id = random_string(5)
879+
stack = (
880+
format_stack()[-2]
881+
.replace("/home/eric/Documents/github/element/synapse/", "")
882+
.replace(
883+
"/home/eric/.cache/pypoetry/virtualenvs/matrix-synapse-xCtC9ulO-py3.13/lib/",
884+
"",
885+
)
886+
.replace("\n", "->")
887+
)
888+
840889
current = current_context()
890+
logger.info(
891+
"asdf run_in_background1 %s start context=%s - %s",
892+
instance_id,
893+
current,
894+
stack,
895+
)
896+
841897
try:
842898
res = f(*args, **kwargs)
843899
except Exception:
@@ -868,6 +924,12 @@ def run_in_background(
868924

869925
# The function may have reset the context before returning, so
870926
# we need to restore it now.
927+
logger.info(
928+
"asdf run_in_background2 %s restore log context=%s - %s",
929+
instance_id,
930+
current,
931+
stack,
932+
)
871933
ctx = set_current_context(current)
872934

873935
# The original context will be restored when the deferred
@@ -882,7 +944,17 @@ def run_in_background(
882944
# which is supposed to have a single entry and exit point. But
883945
# by spawning off another deferred, we are effectively
884946
# adding a new exit point.)
885-
d.addBoth(_set_context_cb, ctx)
947+
948+
def _asdf(result: ResultT, context: LoggingContextOrSentinel) -> ResultT:
949+
logger.info(
950+
"asdf run_in_background3 %s reset log context at end ctx=%s - %s",
951+
instance_id,
952+
ctx,
953+
stack,
954+
)
955+
return _set_context_cb(result, context)
956+
957+
d.addBoth(_asdf, ctx)
886958
return d
887959

888960

@@ -901,6 +973,15 @@ def run_coroutine_in_background(
901973
do not run until called, and so calling an async function without awaiting
902974
cannot change the log contexts.
903975
"""
976+
stack = (
977+
format_stack()[-2]
978+
.replace("/home/eric/Documents/github/element/synapse/", "")
979+
.replace(
980+
"/home/eric/.cache/pypoetry/virtualenvs/matrix-synapse-xCtC9ulO-py3.13/lib/",
981+
"",
982+
)
983+
.replace("\n", "->")
984+
)
904985

905986
current = current_context()
906987
d = defer.ensureDeferred(coroutine)
@@ -921,7 +1002,15 @@ def run_coroutine_in_background(
9211002
# which is supposed to have a single entry and exit point. But
9221003
# by spawning off another deferred, we are effectively
9231004
# adding a new exit point.)
924-
d.addBoth(_set_context_cb, ctx)
1005+
def _asdf(result: ResultT, context: LoggingContextOrSentinel) -> ResultT:
1006+
logger.info(
1007+
"asdf run_coroutine_in_background reset log context at end ctx=%s - %s",
1008+
ctx,
1009+
stack,
1010+
)
1011+
return _set_context_cb(result, context)
1012+
1013+
d.addBoth(_asdf, ctx)
9251014
return d
9261015

9271016

@@ -940,15 +1029,56 @@ def make_deferred_yieldable(deferred: "defer.Deferred[T]") -> "defer.Deferred[T]
9401029
9411030
(This is more-or-less the opposite operation to run_in_background.)
9421031
"""
1032+
instance_id = random_string(5)
1033+
stack = (
1034+
format_stack()[-2]
1035+
.replace("/home/eric/Documents/github/element/synapse/", "")
1036+
.replace(
1037+
"/home/eric/.cache/pypoetry/virtualenvs/matrix-synapse-xCtC9ulO-py3.13/lib/",
1038+
"",
1039+
)
1040+
.replace("\n", "->")
1041+
)
1042+
full_stack = [
1043+
x.replace("/home/eric/Documents/github/element/synapse/", "").replace(
1044+
"/home/eric/.cache/pypoetry/virtualenvs/matrix-synapse-xCtC9ulO-py3.13/lib/",
1045+
"",
1046+
)
1047+
for x in format_stack()
1048+
]
1049+
logger.info(
1050+
"asdf make_deferred_yieldable1 %s start - %s - full stack=%s",
1051+
instance_id,
1052+
stack,
1053+
full_stack,
1054+
)
1055+
9431056
if deferred.called and not deferred.paused:
9441057
# it looks like this deferred is ready to run any callbacks we give it
9451058
# immediately. We may as well optimise out the logcontext faffery.
9461059
return deferred
9471060

9481061
# ok, we can't be sure that a yield won't block, so let's reset the
9491062
# logcontext, and add a callback to the deferred to restore it.
1063+
logger.info(
1064+
"asdf make_deferred_yieldable2 %s reset log context - %s - full stack=%s",
1065+
instance_id,
1066+
stack,
1067+
full_stack,
1068+
)
9501069
prev_context = set_current_context(SENTINEL_CONTEXT)
951-
deferred.addBoth(_set_context_cb, prev_context)
1070+
1071+
def _asdf(result: ResultT, context: LoggingContextOrSentinel) -> ResultT:
1072+
logger.info(
1073+
"asdf make_deferred_yieldable3 %s restore log context at end ctx=%s - %s - full stack=%s",
1074+
instance_id,
1075+
prev_context,
1076+
stack,
1077+
full_stack,
1078+
)
1079+
return _set_context_cb(result, context)
1080+
1081+
deferred.addBoth(_asdf, prev_context)
9521082
return deferred
9531083

9541084

synapse/metrics/background_process_metrics.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
ContextResourceUsage,
4949
LoggingContext,
5050
PreserveLoggingContext,
51+
run_in_background,
5152
)
5253
from synapse.logging.opentracing import SynapseTags, start_active_span
5354
from synapse.metrics import SERVER_NAME_LABEL
@@ -244,6 +245,9 @@ def run_as_background_process(
244245
Note that the returned Deferred does not follow the synapse logcontext
245246
rules.
246247
"""
248+
# TODO: Remove
249+
if desc != "rspsr":
250+
return
247251

248252
async def run() -> Optional[R]:
249253
with _bg_metrics_lock:
@@ -258,7 +262,7 @@ async def run() -> Optional[R]:
258262
).inc()
259263

260264
with BackgroundProcessLoggingContext(
261-
name=desc, server_name=server_name, instance_id=count
265+
name="bg-" + desc, server_name=server_name, instance_id=count
262266
) as context:
263267
try:
264268
if bg_start_span:
@@ -285,6 +289,8 @@ async def run() -> Optional[R]:
285289
# looping_call and other places that expect a Deferred.
286290
return defer.ensureDeferred(run())
287291

292+
# return run_in_background(run)
293+
288294

289295
P = ParamSpec("P")
290296

synapse/storage/database.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,7 @@ def inner_func(conn: _PoolConnection, *args: P.args, **kwargs: P.kwargs) -> R:
10491049
assert not self.engine.in_transaction(conn)
10501050

10511051
with LoggingContext(
1052-
str(curr_context), parent_context=parent_context
1052+
"db-" + str(curr_context), parent_context=parent_context
10531053
) as context:
10541054
with opentracing.start_active_span(
10551055
operation_name="db.connection",

synapse/storage/databases/main/room.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,26 +1479,26 @@ async def get_partial_state_room_resync_info(
14791479
for room_id, joined_via in rows:
14801480
room_servers[room_id] = PartialStateResyncInfo(joined_via=joined_via)
14811481

1482-
rows = cast(
1483-
List[Tuple[str, str]],
1484-
await self.db_pool.simple_select_list(
1485-
"partial_state_rooms_servers",
1486-
keyvalues=None,
1487-
retcols=("room_id", "server_name"),
1488-
desc="get_partial_state_rooms",
1489-
),
1490-
)
1491-
1492-
for room_id, server_name in rows:
1493-
entry = room_servers.get(room_id)
1494-
if entry is None:
1495-
# There is a foreign key constraint which enforces that every room_id in
1496-
# partial_state_rooms_servers appears in partial_state_rooms. So we
1497-
# expect `entry` to be non-null. (This reasoning fails if we've
1498-
# partial-joined between the two SELECTs, but this is unlikely to happen
1499-
# in practice.)
1500-
continue
1501-
entry.servers_in_room.add(server_name)
1482+
# rows = cast(
1483+
# List[Tuple[str, str]],
1484+
# await self.db_pool.simple_select_list(
1485+
# "partial_state_rooms_servers",
1486+
# keyvalues=None,
1487+
# retcols=("room_id", "server_name"),
1488+
# desc="get_partial_state_rooms",
1489+
# ),
1490+
# )
1491+
1492+
# for room_id, server_name in rows:
1493+
# entry = room_servers.get(room_id)
1494+
# if entry is None:
1495+
# # There is a foreign key constraint which enforces that every room_id in
1496+
# # partial_state_rooms_servers appears in partial_state_rooms. So we
1497+
# # expect `entry` to be non-null. (This reasoning fails if we've
1498+
# # partial-joined between the two SELECTs, but this is unlikely to happen
1499+
# # in practice.)
1500+
# continue
1501+
# entry.servers_in_room.add(server_name)
15021502

15031503
return room_servers
15041504

0 commit comments

Comments
 (0)