发布

  • fix(core): avoid overwhelming DB with connections during analytics init (#34881)

    frostbyte_neo 发布于 2026-03-17 19:34:51 +00:00

    Current Behavior

    Every process that initializes analytics opens its own DB connection to
    get/create a session ID. This includes the CLI, the daemon, and every
    plugin worker
    . In workspaces with many plugins, dozens of plugin
    workers spawn simultaneously, each opening a DB connection and
    querying/writing session metadata. This overwhelms the SQLite database
    with concurrent connections and causes failures.

    How This Fixes It

    The root cause is that plugin workers each independently open a DB
    connection just to read the session ID. The fix eliminates this by
    having the parent process (CLI or daemon) fetch the session ID once and
    pass it to child processes via the NX_ANALYTICS_SESSION_ID environment
    variable. Plugin workers inherit this env var and initialize telemetry
    without touching the DB at all.

    Process Before After
    CLI Opens DB connection Opens DB connection (1x)
    Daemon Opens DB connection Opens DB connection (1x)
    Plugin worker (×N) Each opens DB connection Reads env var, **no DB
    connection**

    In a workspace with 20 plugins, this reduces DB connections from 22 (CLI

    • daemon + 20 workers) down to 2 (CLI + daemon only).

    Two Initialization Paths

    • initializeTelemetry(dbConnection, ...) — Used by CLI and daemon.
      Gets/creates the session ID from the DB via a transaction, stores the
      connection for persisting session refreshes on flush, and returns the
      session ID so the caller can set it as an env var for child processes.
    • initializeTelemetryWithSessionId(sessionId, ...) — Used by
      plugin workers. Takes the session ID inherited from the parent process
      env var. No DB connection, no DB queries.

    Session Refresh for Long-Lived Processes

    The daemon is long-lived and could hold a stale session ID for hours.
    The telemetry background thread now tracks activity and generates a new
    session ID after 30 minutes of inactivity (matching the existing GA4
    session timeout). When a session refreshes, the background thread
    notifies the main thread via a channel, which persists the new session
    to the DB in a transaction on flush.

    Other Changes

    • Extracted TelemetryOptions struct to replace the long parameter list
      in TelemetryService::new
    • Moved SESSION_TIMEOUT_SECS to constants.rs so it can be shared
      between modules
    • Extracted init_service helper to deduplicate between the two init
      paths
    • Extracted persist_session_to_db helper that wraps both metadata
      writes in a transaction
    • Separated session ID retrieval (get_or_create_session_id) from
      telemetry service initialization

    Related Issue(s)

    Fixes database connection exhaustion when many plugin workers initialize
    analytics simultaneously.

    下载附件