Some production chat requests intermittently park forever between the
vector_db whitelist query and TidbOnQdrantVectorFactory.init_vector's
first log line: the message row stays status=normal with an empty answer,
no error is recorded, and no timeout ever fires. Live captures place the
freeze inside Vector._init_vector's factory resolution, but the API runs
gevent workers and a parked greenlet is invisible to py-spy (default and
--native modes both show only idle hubs), so the exact parking statement
cannot be captured from outside the process.
INFO-level breadcrumbs added:
- vector_factory._init_vector: before/after get_vector_factory, with
tenant_id + dataset_id for correlating a hung request with its logs
- vector_backend_registry: cache-miss marker, and before/after ep.load()
with the entry point value (module about to be imported)
Decoding the log tail of the next hung request:
- "resolving..." absent -> parked before resolution
- "resolving..." only, no miss log -> parked on the cache-hit path or
inside logging itself (handler lock)
- cache miss, no "loading..." -> parked in entry_points() scan
- "loading...", no "... loaded" -> parked inside ep.load() import
(import lock / gevent interaction)
- "resolved...", no init_vector: -> parked at the factory call boundary
All lines fire at most once per Vector construction; the slow-path lines
fire only on per-process first resolution, so added volume matches the
existing init_vector breadcrumb. Diagnostic instrumentation; no logic
changes, cheap to revert.