bartoszkobylinski opened a new issue, #3742:
URL: https://github.com/apache/iggy/issues/3742

   
   ### Description
   
   The Python binding's `IggyClient` accepts only a connection string, so **no 
client
   configuration can be set from Python** — in particular neither reconnection 
nor auto-login.
   On `master`, `foreign/python/src/client.rs`:
   
   ```rust
   #[new]
   #[pyo3(signature = (conn=None))]
   fn new(conn: Option<String>) -> PyResult<Self>
   
   let client = IggyClientBuilder::new()
       .with_tcp()
       .with_server_address(conn.unwrap_or("127.0.0.1:8090".to_string()))
       .build()
   ```
   
   The generated stub confirms the surface: the only exported types are 
`AutoCommit`,
   `AutoCommitAfter`, `AutoCommitWhen`, `IggyClient`, `IggyConsumer`, 
`PollingStrategy`,
   `ReceiveMessage`, `SendMessage`, `StreamDetails`, `TopicDetails`. There is 
no config or
   builder type.
   
   ### Why this matters — the SDK's own session recovery becomes unreachable 
from Python
   
   `#2880` added `Unauthenticated`, `Disconnected`, `EmptyResponse` and 
`StaleClient` to the
   reconnect match in `send_raw_with_response`, so the client reconnects **and 
replays the
   stored login**. That recovery is gated on the client having `reconnection` 
enabled and an
   `AutoLogin` credential to replay — and `#3651` documents the other half:
   
   > *"`login_user` / `logout_user` … 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`"*
   
   A Python user has **only** the manual `connect()` + `login_user()` flow 
available. So the
   combination is: no auto-login to replay, and a flow that does not own 
session state. The
   practical result is that a session lost shortly after login is not recovered 
— it surfaces as
   `Unauthenticated` on the *next* call, and the application must handle it by 
hand.
   
   ### Observed impact
   
   A long-running Python consumer on a restart loop, against `iggy-server` 
0.8.0 over TCP
   loopback. `login_user()` returned successfully; the very next call raised:
   
   ```
   File ".../core/iggy_bus.py", line 229, in ensure_topology
       if await self._client.get_stream(self._stream) is None:
   RuntimeError: Unauthenticated
   ```
   
   Ten seconds later the same startup failed differently, then succeeded on the 
third attempt
   and ran for ~2h48m:
   
   ```
   File ".../core/iggy_bus.py", line 206, in connect
       await self._client.login_user(...)
   RuntimeError: Disconnected
   ```
   
   Both are errors `#2880` already classifies as reconnectable — but with no 
reconnection/
   auto-login configurable from Python, they terminate the process instead, 
leaving restart
   supervision (systemd) as the only recovery.
   
   ### Workaround a Python caller has to hand-roll today
   
   Because `login_user()` returning is not sufficient evidence of an 
authenticated session, we
   now re-verify it explicitly and re-login on failure — effectively 
reimplementing `auto_login`
   plus reconnection in Python:
   
   ```python
   for attempt in range(MAX_ATTEMPTS):
       try:
           await client.connect()
           await client.login_user(username, password)
           await client.get_stream(stream)   # probe: raises Unauthenticated if 
the session is dead
       except Exception:
           await sleep_with_backoff(attempt)  # then retry the whole 
connect+login
       else:
           break
   ```
   
   ### Parity — other foreign SDKs already expose this
   
   - Go: `foreign/go/client/tcp/tcp_core.go` — `autoLogin AutoLogin`
   - C#: `foreign/csharp/Iggy_SDK/Configuration/AutoLoginSettings.cs`
   
   Python is the outlier.
   
   ### Suggested direction
   
   Everything needed already exists on the Rust side; this is about exposing it:
   
   - `core/common/src/types/configuration/tcp_config/tcp_client_config.rs` — 
`TcpClientConfig`
   - `.../tcp_client_config_builder.rs` — `with_auto_sign_in(AutoLogin)`
   - `.../tcp_client_reconnection_config.rs` — `TcpClientReconnectionConfig`
   - `core/common/src/types/configuration/auth_config/auto_login.rs` — 
`AutoLogin`
   - `core/sdk/src/clients/client_builder.rs` — 
`IggyClientBuilder::with_auto_sign_in`
   
   Minimal version: optional keyword arguments on `IggyClient(...)` for 
reconnection settings
   and auto-login credentials, passed through to `IggyClientBuilder`. Fuller 
version: expose a
   config/builder object mirroring `TcpClientConfigBuilder`, which would also 
give the Python
   SDK somewhere to hang the QUIC/HTTP/WebSocket options from `#2835`.
   
   Happy to open a PR if a maintainer indicates the preferred shape (kwargs vs. 
exposed builder).
   
   ### Affected area / component
   
   Python SDK (`foreign/python`)
   
   ### Related
   
   - `#3651` — SDK client state conflates transport and session dimensions 
(explains why the
     manual `connect()` + `login_user()` flow does not own session state). 
Related, not a
     duplicate: that issue is about the state enum being unreliable; this one 
is about the
     configuration surface being absent in Python.
   - `#2880` — added the reconnect-and-replay-login behavior that this config 
would unlock.
   - `#1453` — `with_auto_sign_in` for the Rust builders.
   - `#2835` — Python SDK transports; a config object would be the natural home 
for those too.
   
   ### Versions
   
   Server `0.8.0` (DockerHub `apache/iggy:0.8.0`), `apache-iggy` 0.8.0 (PyPI 
wheel, cp312,
   manylinux), Python 3.12.13, TCP on loopback. Python constructor and builder 
call quoted above
   were read on `master`, so the gap is present there too.
   
   ### Scope note
   
   This issue is deliberately limited to the **missing configuration surface in 
the Python
   binding**. Whether a session can still be lost immediately after a 
successful `login_user()`
   *even with* auto-login and reconnection enabled is a separate Rust/server 
question that we
   have not isolated, and it is not claimed here.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to