TurboGears / TurboGears/backlash

Add ASGI support for TraceSlowRequestsMiddleware (slow request tracing)

Open
#26 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
13
Forks
13
PR merge metrics
No merged PRs in 30d

Description

Goal

Provide an ASGI counterpart to TraceSlowRequestsMiddleware so ASGI applications can get slow-request stack reports through the existing reporters (email, Sentry).

Done criteria:

  • A new AsgiTraceSlowRequestsMiddleware that:
    • Passes through non-http scopes (websocket, lifespan) untouched.
    • On request start, registers a timer job (reusing the existing Timer machinery) that fires after interval seconds; on completion or error, cancels it.
    • When the timer fires, snapshots the stack of the request's asyncio.Task and reports it through the configured reporters with the same SLOW_REQUEST context shape (task/process identifiers, start time).
    • Honors exclude_paths against the ASGI path.
  • A task-based stack capture in frtools (sibling of get_thread_stack) built on asyncio.Task.get_stack(), producing the same Traceback object reporters already consume.
  • Behavior covered by in-process ASGI tests (e.g. an app that awaits past a short interval → report fired; fast app → no report; excluded path → no tracing).

Key design constraint: the WSGI implementation snapshots the worker thread via sys._current_frames()[thread_ident]. Under an event loop all requests share one thread, so a thread snapshot captures whichever coroutine happens to be running — garbage. The request-local handle must be the task itself (asyncio.current_task() at request start), and the snapshot target Task.get_stack().

Known wrinkles to resolve during implementation:

  • The timer fires on a separate thread; Task.get_stack() is not documented as thread-safe. Consider marshalling the snapshot onto the loop with loop.call_soon_threadsafe before reporting.
  • Sync endpoints offloaded to a threadpool (e.g. Starlette run_in_threadpool) will show the task awaiting the executor rather than the real user stack. Acceptable as a first pass, but worth documenting; a follow-up could correlate the executor thread and fall back to get_thread_stack.

Why

#23 and #25 bring the debugger and crash reporting to ASGI; slow-request tracing is the remaining WSGI-only capability. Unlike #25 this is not a mechanical port — the snapshot mechanism must change from thread-based to task-based — but the surrounding scaffolding (timer scheduling, job cancellation, context injectors, reporters, Traceback rendering) is reusable as-is, so the genuinely new piece is confined to task stack capture in frtools.

References

  • backlash/tracing/slowrequests/middleware.py (TraceSlowRequestsMiddleware) — WSGI logic to mirror: timer scheduling, BACKLASH_SLOW_TRACING_JOBS multi-registration guard, peek reporting flow.
  • backlash/tracing/slowrequests/timer.py (Timer) — reusable scheduling thread.
  • backlash/frtools.py (get_thread_stack, DumpThread) — thread-based capture the task-based sibling should mirror.
  • backlash/asgi.py (AsgiDebuggedApplication, from #23) — established ASGI shell patterns: scope filtering, scope-based context injectors, logger/stderr error sink.
  • Issue: Add ASGI support for TraceErrorsMiddleware (crash reporting) #25 — sibling effort sharing the ASGI conventions.
  • Issue: Add ASGI support for the interactive debugger #23 — parent effort.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read backlash/tracing/slowrequests/middleware.py and timer.py first, then compare backlash/frtools.py with the ASGI patterns in backlash/asgi.py. Run or add in-process ASGI tests covering slow, fast, excluded, and non-http scopes. Done means task-based stack reports use the existing reporters and context, while timers cancel on completion or error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.