Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Session] Root #3393

Closed
wants to merge 23 commits into from
Closed

[Session] Root #3393

wants to merge 23 commits into from

Conversation

estrattonbailey
Copy link
Member

@estrattonbailey estrattonbailey commented Apr 3, 2024

The core issue being solved here is a race condition between the update of currentAccount and the __globalAgent. #3333 set us up so that changing accounts gives us a fresh query cache, which was the impetus behind __globalAgent in the first place (stale closures).

This PR builds on that by deriving currentAccount from the currently active BskyAgent, removing the need to manage updates to two objects (currentAccount and __globalAgent) that have the same lifetime.

In the process, I also split out state handling into separate useState calls to help avoid loops and isolate updates.

  • derive currentAccount from BskyAgent.session 4482cbf1436113e1a34c4903bb26635417d1a8cd
  • replace mutation of this global state with a call to refresh the session and re-derive ff36564c9b9fc5776de5936e991f33487c4ceafe
  • replace usages of previous mutation of global state 80b562cfacf703d2807e9c81f67e187ad43c6017
  • refactored persistSession handler for more clarity 634995db38a2f7a3d6b4871b66cafb8480d86877

With this PR, we should now reference the active BskyAgent via { agent } = useSession() and drop the __globalAgent.

Review state/session.ts without whitespace.

Base automatically changed from replace-query-client to main April 4, 2024 01:51
Copy link

github-actions bot commented Apr 4, 2024

Old size New size Diff
6.34 MB 6.34 MB -1.94 KB (-0.03%)

Comment on lines 52 to 55
updateCurrentAccount({
email: email.trim(),
emailConfirmed: false,
})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think this was actually a Bad Thing™. We treat currentAccount as a read-only representation of server state, but in this case we also mutated it and used it to dictate UI state.

I've replaced it with a call to refresh the session and derive currentAccount from that data.

Comment on lines 571 to 609
// as we migrate, continue to keep this updated
__globalAgent = agent

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gaearon special note of this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do a pass to use a hook first? And then replace the implementation.

@estrattonbailey estrattonbailey marked this pull request as ready for review April 4, 2024 19:01
@estrattonbailey estrattonbailey changed the title Session alignment Fix race condition, derive currentAccount from active session Apr 4, 2024
const [isInitialLoad, setIsInitialLoad] = React.useState(true)
const [isSwitchingAccounts, setIsSwitchingAccounts] = React.useState(false)
const currentAccount = React.useMemo(
() => agentToSessionAccount(agent),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes that once agent gets into state, its .session and nested fields (e.g. .session.refreshJwt) never changes. Can we make that assumption?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, can rename those to nextAgent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good shout. Those fields are managed internally by BskyAgent. Example: when accessJwt expires, the agent automatically calls refreshSession which updates the session internally. Calls to the currentAgent in client code then automatically use the updated session.

This made me realize how important it is to ensure that fresh tokens get synced across tabs though, gonna triple check that...

Copy link
Collaborator

@gaearon gaearon Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If agent is something that can be mutated on its own, it isn't right to use it as a useMemo input. Since nothing will trigger re-evaluation when these fields change. Let's sync up tomorrow to chat more about this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setAgent is called when switching accounts, so each account always has its own agent, and currentAccount can be derived from it. What I'm explaining above isn't something we need to handle directly in this case.

src/state/session/index.tsx Outdated Show resolved Hide resolved
Copy link

github-actions bot commented Apr 4, 2024

Old size New size Diff
6.36 MB 6.36 MB -549 B (-0.01%)

Copy link
Collaborator

@gaearon gaearon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chatted out of band about this, seems like a promising direction with a few things to fix

@estrattonbailey estrattonbailey changed the title Fix race condition, derive currentAccount from active session [Session] Root Apr 13, 2024
@estrattonbailey
Copy link
Member Author

Superseded by #3541 and stack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants