Skip to content

Commit 15f7a9d

Browse files
committed
Commit
1 parent 39fb803 commit 15f7a9d

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

drift/instrumentation/django/middleware.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@ def _handle_replay_request(self, request: HttpRequest, sdk) -> HttpResponse:
105105
logger.warning("[DJANGO_MIDDLEWARE] No replay_trace_id found in headers, proceeding without span")
106106
return self.get_response(request)
107107

108+
# Start time travel as early as possible (inbound request start) to ensure deterministic
109+
# behavior for time-dependent code paths, especially cache key generation (e.g. django-cachalot).
110+
root_timestamp = headers_lower.get("http_x_td_root_timestamp")
111+
if root_timestamp:
112+
try:
113+
from drift.instrumentation.datetime.instrumentation import start_time_travel
114+
115+
start_time_travel(root_timestamp, trace_id=replay_trace_id)
116+
except Exception as e:
117+
logger.debug(f"[DJANGO_MIDDLEWARE] Failed to start time travel from x-td-root-timestamp: {e}")
118+
108119
# Set replay trace context
109120
replay_token = replay_trace_id_context.set(replay_trace_id)
110121

drift/instrumentation/fastapi/instrumentation.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,17 @@ async def _handle_replay_request(
131131

132132
logger.debug(f"[FastAPIInstrumentation] Setting replay trace ID: {replay_trace_id}")
133133

134+
# Start time travel at inbound request start when provided by CLI.
135+
# This prevents time drift before the first outbound span is matched (critical for cache keys).
136+
root_timestamp = headers_lower.get("x-td-root-timestamp")
137+
if root_timestamp:
138+
try:
139+
from drift.instrumentation.datetime.instrumentation import start_time_travel
140+
141+
start_time_travel(root_timestamp, trace_id=replay_trace_id)
142+
except Exception as e:
143+
logger.debug(f"[FastAPIInstrumentation] Failed to start time travel from x-td-root-timestamp: {e}")
144+
134145
# Remove accept-encoding header to prevent compression during replay
135146
# (responses are stored decompressed, compression would double-compress)
136147
if "accept-encoding" in headers_lower:

drift/instrumentation/wsgi/handler.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,17 @@ def _handle_replay_request(
142142
# No trace context in REPLAY mode; proceed without span
143143
return original_wsgi_app(app, environ, start_response)
144144

145+
# Start time travel at inbound request start when provided by CLI.
146+
# This prevents time drift before the first outbound span is matched (critical for cache keys).
147+
root_timestamp = headers_lower.get("x-td-root-timestamp")
148+
if root_timestamp:
149+
try:
150+
from drift.instrumentation.datetime.instrumentation import start_time_travel
151+
152+
start_time_travel(root_timestamp, trace_id=replay_trace_id)
153+
except Exception as e:
154+
logger.debug(f"[WSGI] Failed to start time travel from x-td-root-timestamp: {e}")
155+
145156
# Set replay trace context
146157
replay_token = replay_trace_id_context.set(replay_trace_id)
147158

0 commit comments

Comments
 (0)