Skip to content

Run the Integration.register() loop off the main thread (two-phase init) #5704

Description

@runningcode

Problem

Sentry.init registers all integrations synchronously on the calling thread (sentry/src/main/java/io/sentry/Sentry.java:374-385) — the main thread under auto-init. With ~17 default Android integrations this is the biggest remaining block of main-thread init work once the per-integration items (NDK etc.) are fixed.

Proposal

Keep a minimal synchronous core — options, scopes, SentryClient binding, UncaughtExceptionHandlerIntegration — and submit the rest of the registration loop to options.getExecutorService(), with an opt-in marker for integrations that genuinely need the main thread (AppLifecycleIntegration already self-posts when off-main).

Sentry.captureX immediately after init() keeps working: the client is bound synchronously and events queue on the transport.

Constraints

  • The deliberate startup-crash blocking flush (sentry-android-core/.../SendCachedEnvelopeIntegration.java:151-161) must still block init() — needs an explicit carve-out.
  • Integration ordering guarantees (NDK before outbox watcher, AppLifecycle before ANR, ANR before Replay — see comments in AndroidOptionsInitializer.installDefaultIntegrations) must be preserved. The single-threaded executor keeps submission order, but mixed sync/async registration could break it; audit each.
  • Session auto-start + isForegroundImportance() at the end of SentryAndroid.init (SentryAndroid.java:184-203) depend on integration state (LifecycleWatcher) — decide whether they move too.

Concrete follow-up to #5475 ("Move more init code async").

Metadata

Metadata

Assignees

No one assigned

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions