Skip to content

Instrument Authress login flow with timing logs and a diagnostic overlay - #8

Merged
wparad merged 4 commits into
mainfrom
claude/authress-login-performance-9tzo38
Aug 15, 2026
Merged

Instrument Authress login flow with timing logs and a diagnostic overlay#8
wparad merged 4 commits into
mainfrom
claude/authress-login-performance-9tzo38

Conversation

@wparad

@wparad wparad commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to the "why is Authress login slow" investigation: adds the instrumentation needed to actually see where time goes, plus a way to view it without hooking up logcat.

  • AuthressLoginClient's shared execute() now logs every Authress request/response with elapsed ms (request start, network failure, and success/failure all timed), and authenticate() / completeAuthenticationRequest() separately log how long the anti-abuse proof-of-work search takes vs. the network round trip.
  • JwtManager.calculateAntiAbuseHash is now suspend and dispatches its busy-loop search to Dispatchers.Default internally, so it can't block the Main thread just because a caller (e.g. LoginScreen's rememberCoroutineScope) happened to launch it there.
  • LoginScreen's post-sign-in mailbox load is now timed and logged too.
  • New DebugLogOverlay composable: a persistent cog button in the bottom-right corner during onboarding and the login screen that opens a scrollable, color-coded (info/warn/error) log panel reading from the existing Room-backed AppLogger — the same log store already exposed in Settings > Logs, just reachable before a session exists.

Test plan

  • Manual: run through onboarding → login → mailbox load, confirm the cog opens/closes the log panel and shows Authress timing entries with plausible durations
  • Manual: confirm Copy/Clear in the panel work and match the existing Settings > Logs behavior
  • Could not run a full Gradle build in this environment (no Android SDK available in the sandbox); changes were reviewed manually against existing call sites and no test suite references the touched files

Generated by Claude Code

claude added 4 commits August 15, 2026 12:42
…overlay

Every Authress call now logs its duration (including the anti-abuse
proof-of-work search and the network round trip separately), and the
proof-of-work hash is dispatched to Dispatchers.Default so it no longer
runs on the Main thread just because callers launch it from a Compose
rememberCoroutineScope. Onboarding and the login screen now show a cog
button that opens a scrollable, color-coded log panel backed by the
existing AppLogger, so a slow or stuck sign-in can be diagnosed in place.
…ogging

- CI caught two real compile errors from the previous commit: the
  anti-abuse hash's suspend/withContext refactor inferred Unit instead of
  String, and DebugLogOverlay was missing the setValue operator import for
  its `var expanded by remember {...}`. Both fixed.
- Found and fixed a real bug while adding request timing: AuthressLoginClient
  was built from the same OkHttpClient as the Email API, which carries
  AuthInterceptor. That interceptor waits on waitForToken() — before a
  session exists, every unauthenticated Authress call (including the very
  POST /authentication that starts login) blocked for its full 5s timeout
  waiting for a session that only that same call could establish. Authress
  now gets its own client without AuthInterceptor.
- Logging now covers more than the login path: ApiLoggingInterceptor gives
  the Email API the same production-visible request timing Authress calls
  already had (HttpLoggingInterceptor is debug-only), and ThreadRepository's
  syncPending/SyncForegroundService — previously silent — now log queue
  sizes, per-item failures, and tick duration.
- authenticate()/completeAuthenticationRequest() split into more granular
  AuthStatus/LoginStep stages (RequestingAuthenticationUrl, OpeningBrowser,
  AwaitingRedirect, VerifyingRedirect, ExchangingToken) so the sign-in
  checklist shows which specific call is slow instead of one wide phase.
- Diagnosed "authentication request mismatch": tapping "Try again" while an
  earlier Custom Tab is still alive starts a second attempt: the old tab can
  still redirect back with the old authenticationRequestId after storage has
  moved on to the new one. authenticate() now logs when it abandons a live
  attempt, and the mismatch log line names both the pending and redirect IDs
  so the two can be correlated instead of the mismatch looking unexplained.
…a token

AuthInterceptor ran on OkHttp's dispatcher pool for every Email API request
and used runBlocking to await AuthressLoginClient.waitForToken() there. That
mixes concerns: waiting for a browser-driven login the request has nothing
to do with is a foreground/UI concern, not something a background
request-attachment interceptor should block a pool thread on. It's also
exactly what caused the earlier 5s stall bug (a request racing an
in-progress login could block behind an unrelated flow).

AuthInterceptor now takes a synchronous, non-suspending token provider and
attaches whatever token is cached right now via getToken() — never waits.
waitForToken() stays available for a foreground caller that deliberately
wants to gate on sign-in (the login screen), which is the only place it
should ever be awaited from.
Walking back the previous commit's change to a synchronous, non-waiting
AuthInterceptor: waitForToken() belongs exactly there — it's the HTTP call
wrapper grabbing a token right before an Email API request goes out, which
is the one legitimate caller for it. That's safe (runBlocking inside an
OkHttp interceptor never touches the main thread) specifically because
Authress's own client (authHttpClient) never carries this interceptor —
that split, not removing the wait, is what actually fixed the earlier 5s
stall bug (POST /authentication waiting on a session only it could create).

No other caller for waitForToken() exists or should; doc comments on it,
AuthInterceptor, and AppContainer now say so directly instead of describing
a foreground caller that was never wired up.
@wparad
wparad merged commit 541e3be into main Aug 15, 2026
2 checks passed
@wparad
wparad deleted the claude/authress-login-performance-9tzo38 branch August 15, 2026 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants