SDK client state conflates transport and session dimensions; Authenticated is never reached
- Dominant language
- Rust
- Stars
- 4.9k
- Forks
- 432
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 173
Description
### Description
### Context
>
> This is AI generated, but I promise this is a real issue, currently Rust SDK doesn't
> manage its state correctly, and I believe it will cause more problem in the long-term.
>
While bringing the Go SDK TCP client to reconnection parity with the Rust
SDK (#3650), I traced how `ClientState` is managed across the Rust
transports and found that the enum mixes two independent dimensions, with
observable gaps in every transport.
### Problem
`ClientState` (core/common/src/types/client_state/mod.rs) flattens two
orthogonal facts into one ladder:
- transport: `Disconnected` / `Connecting` / `Connected`
- session: `Authenticating` / `Authenticated`
A client that is connected and signed in holds both facts simultaneously,
but the enum can store only one value. In practice:
1. **`Authenticated` is dead in all three transports.** There is no
`set_state(ClientState::Authenticated)` call site in `tcp_client.rs`,
`quic_client.rs`, or `websocket_client.rs`. After a successful
connect + auto sign-in, the client reports `authenticating` forever
(set at tcp_client.rs:562/584, never transitioned afterwards).
Anything that observes the state (logs, diagnostics) reads a value
that is wrong for the entire authenticated lifetime of the client.
2. **Session operations do not own session state.** `login_user` /
`logout_user` (clients/binary_users.rs, client_wrappers/
binary_user_client.rs) never touch the state. The only writer of the
session values is `connect()`'s auto-login block, so a manual
`connect()` + `login_user()` flow stays at `Connected`, and there is
no downgrade after `logout_user` because "connected but logged out"
has no representable value.
3. **Readers must enumerate value runs.** `connect()`'s early return
matches `Connected | Authenticating | Authenticated`
(tcp_client.rs:369-371) just to express "transport is up".
None of this currently changes behavior, because every read site treats
`Connected`, `Authenticating`, and `Authenticated` identically. It is
structural debt: the state is unreliable as a source of truth, and the
same transitions are hand-maintained in three transports that have
already drifted apart.
### Affected area / component
Rust SDK, and other language if they use the same state design as Rust
### Proposed solution
Split the dimensions: a transport state (`Disconnected` / `Connecting` /
`Connected` / `Shutdown`) and a separate session state (`Authenticated` /
`Authenticating` / `Unauthenticated`)
Update `connect`, `login_user`, etc. They should update the session/transport state
correctly. For example, in `login_user`, when login is done, we set state to `authenticated`
instead of do nothing.
### Alternatives considered
_No response_
### Contribution
- [ ] I'm willing to submit a pull request to implement this feature
### Good first issue
- [ ] I think this could be a good first issue for a new contributor
Contributor guide
Research direction
Start by reading core/common/src/types/client_state/mod.rs and the state transitions in tcp_client.rs, quic_client.rs, and websocket_client.rs. Trace connect, login_user, and logout_user through clients/binary_users.rs and client_wrappers/binary_user_client.rs. Done means transport and session dimensions are represented and updated consistently, including manual login, logout, and authenticated connections.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100