Skip to content

fix(scraper): push cookie, pageId and authUser to the scraper as one snapshot - #37

Open
Me-xico wants to merge 1 commit into
maxrave-dev:multiplatformfrom
Me-xico:fix/session-props-atomic
Open

Me-xico wants to merge 1 commit into
maxrave-dev:multiplatformfrom
Me-xico:fix/session-props-atomic

Conversation

@Me-xico

@Me-xico Me-xico commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

What & why

Follow-up to #36 / maxrave-dev/SimpMusic#2505. That fix added authUser next to pageId,
but the three session values still reached the scraper through three independent DataStore
collectors, and Ytmusic stored them as three plain vars read one by one in ytClient().
A request built right after an account switch could carry a new pageId with the previous
authuser or cookie, for a short window.

  • DataStoreManager.youTubeSession: one flow over one Preferences snapshot
    (distinctUntilChanged, since data re-emits on every unrelated preference).
  • CommonRepositoryImpl: one collector calling YouTube.setSession(...) first, synchronously.
    visitorData is refreshed only when the cookie changes (same trigger as before, tracked
    with lastCookie, committed only on a successful fetch); the netscape cookie file is
    written once per session change (was twice).
  • Ytmusic: @Volatile private var session: Session swapped as one immutable object;
    ytClient() and getAuthorizationHeader() read it once. cookie/pageId/authUser
    are read-only now, setSession is the only writer. The cached cookieMap is gone: the
    SAPISID map is parsed from the cookie actually sent (customCookie ?: session cookie).
  • AccountRepositoryImpl.getAccountInfo no longer writes youTube.cookie directly: both
    callers already wrote DataStore and the request passes the cookie explicitly.
  • Drive-by: getAuthorizationHeader() had if (...) null without return (no callers).

Not changed, worth knowing: parseCookieString throws on a ; -segment without =; it
now runs per request instead of inside the collector, so a bad pasted cookie no longer
kills the sibling jobs. A guard there is a separate follow-up.

Two pre-existing issues seen while testing, not touched here: every DataStore write
re-emits the proxy flows, removeProxy() sets proxy = null unconditionally and the
setter closes and recreates the HttpClient, so in-flight requests fail with
executor rejected (hit the visitorData() request on every account switch); and
visitorData() currently fails parsing sw.js_data with NoSuchElementException.
I can open issues for both.

Linked issue

Refs maxrave-dev/SimpMusic#2505

Checklist

  • This PR addresses an accepted issue (linked above)
  • I wrote or personally reviewed every line of this change
  • I tested it on Android and/or Desktop — Desktop, run from source on Linux with two
    channels of the same Google account, watching the request log: startup (one session,
    X-Goog-Authuser: 0 + X-Goog-Pageid of the brand channel), switch to the main channel
    (one session, cookie file written once, next browse has no Pageid), switch back (Pageid
    back, never a mixed pair), logout (one session, next requests without Cookie or Pageid).
    Compiled scraper/domain/data for JVM and Android, :desktopApp:jvmMainClasses and
    :composeApp:compileAndroidMain. Not tested: re-login with the same cookie.

…snapshot

setCookie writes the three values in one DataStore edit, but they were
pushed to the scraper by three independent collectors and stored as
three plain vars read one by one while building request headers. After
an account switch a request could still carry the new pageId with the
previous authuser or cookie, for a short window.

DataStoreManager now exposes youTubeSession, a single flow over one
Preferences snapshot; CommonRepositoryImpl collects it and calls
YouTube.setSession. Ytmusic keeps a @volatile immutable Session that
ytClient and getAuthorizationHeader read once per request; the per-field
setters and the cached cookieMap are gone, the SAPISID hash is computed
from the cookie actually sent. visitorData is still refreshed only when
the cookie changes, and the netscape cookie file is written once per
session change instead of twice. AccountRepositoryImpl no longer writes
youTube.cookie directly: both callers already wrote DataStore.

Refs maxrave-dev/SimpMusic#2505
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.

1 participant