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

Commit f18d434

Browse files
committed
Link in both directions between persist_events spans
1 parent 0780047 commit f18d434

File tree

2 files changed

+52
-10
lines changed

2 files changed

+52
-10
lines changed

synapse/logging/opentracing.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def set_fates(clotho, lachesis, atropos, father="Zues", mother="Themis"):
168168
import logging
169169
import re
170170
from functools import wraps
171-
from typing import TYPE_CHECKING, Dict, List, Optional, Pattern, Type
171+
from typing import TYPE_CHECKING, Collection, Dict, List, Optional, Pattern, Type
172172

173173
import attr
174174

@@ -453,12 +453,28 @@ def start_active_span(
453453
)
454454

455455

456-
def start_active_span_follows_from(operation_name, contexts):
456+
def start_active_span_follows_from(
457+
operation_name: str, contexts: Collection, inherit_force_tracing=False
458+
):
459+
"""Starts an active opentracing span, with additional references to previous spans
460+
461+
Args:
462+
operation_name: name of the operation represented by the new span
463+
contexts: the previous spans to inherit from
464+
inherit_force_tracing: if set, and any of the previous contexts have had tracing
465+
forced, the new span will also have tracing forced.
466+
"""
457467
if opentracing is None:
458468
return noop_context_manager()
459469

460470
references = [opentracing.follows_from(context) for context in contexts]
461471
scope = start_active_span(operation_name, references=references)
472+
473+
if inherit_force_tracing and any(
474+
is_context_forced_tracing(ctx) for ctx in contexts
475+
):
476+
force_tracing(scope.span)
477+
462478
return scope
463479

464480

synapse/storage/persist_events.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import logging
1919
from collections import deque
2020
from typing import (
21+
Any,
2122
Awaitable,
2223
Callable,
2324
Collection,
@@ -104,12 +105,17 @@
104105
)
105106

106107

107-
@attr.s(auto_attribs=True, frozen=True, slots=True)
108+
@attr.s(auto_attribs=True, slots=True)
108109
class _EventPersistQueueItem:
109110
events_and_contexts: List[Tuple[EventBase, EventContext]]
110111
backfilled: bool
111112
deferred: ObservableDeferred
112-
opentracing_context: Optional[object]
113+
114+
parent_opentracing_span_contexts: List = []
115+
"""A list of opentracing spans waiting for this batch"""
116+
117+
opentracing_span_context: Any = None
118+
"""The opentracing span under which the persistence actually happened"""
113119

114120

115121
_PersistResult = TypeVar("_PersistResult")
@@ -164,20 +170,36 @@ async def add_to_queue(
164170
end_item = queue[-1]
165171
else:
166172
# need to make a new queue item
167-
span = opentracing.active_span()
168173
deferred = ObservableDeferred(defer.Deferred(), consumeErrors=True)
169174

170175
end_item = _EventPersistQueueItem(
171176
events_and_contexts=[],
172177
backfilled=backfilled,
173178
deferred=deferred,
174-
opentracing_context=span.context if span else None,
175179
)
176180
queue.append(end_item)
177181

182+
# add our events to the queue item
178183
end_item.events_and_contexts.extend(events_and_contexts)
184+
185+
# also add our active opentracing span to the item so that we get a link back
186+
span = opentracing.active_span()
187+
if span:
188+
end_item.parent_opentracing_span_contexts.append(span.context)
189+
190+
# start a processor for the queue, if there isn't one already
179191
self._handle_queue(room_id)
180-
return await make_deferred_yieldable(end_item.deferred.observe())
192+
193+
# wait for the queue item to complete
194+
res = await make_deferred_yieldable(end_item.deferred.observe())
195+
196+
# add another opentracing span which links to the persist trace.
197+
with opentracing.start_active_span_follows_from(
198+
"persist_event_batch_complete", (end_item.opentracing_span_context,)
199+
):
200+
pass
201+
202+
return res
181203

182204
def _handle_queue(self, room_id):
183205
"""Attempts to handle the queue for a room if not already being handled.
@@ -204,10 +226,14 @@ async def handle_queue_loop():
204226
queue = self._get_drainining_queue(room_id)
205227
for item in queue:
206228
try:
207-
with opentracing.start_active_span(
229+
with opentracing.start_active_span_follows_from(
208230
"persist_event_batch",
209-
child_of=item.opentracing_context,
210-
):
231+
item.parent_opentracing_span_contexts,
232+
inherit_force_tracing=True,
233+
) as scope:
234+
if scope:
235+
item.opentracing_span_context = scope.span.context
236+
211237
ret = await self._per_item_callback(
212238
item.events_and_contexts, item.backfilled
213239
)

0 commit comments

Comments
 (0)