Proposal: connections that recover on their own after sleep, network loss and server restarts
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
Research direction
Start with transport/desktop/health_check.rs, application/tunnels.rs, and the existing connection failure handling; review the tunnel cache and proxy/tcp_forward.rs tests. The proposal divides the work into five phases, each with its own tests, and leaves lifecycle behavior, defaults, plugin support, and roadmap placement for maintainers to decide. Done for phase 1 means a tested lifecycle core detects sleep gaps, drops the connection's pools and tunnel, and reconnects once so the next query succeeds.
Written by the indexing model from the issue text.
Description
Problem
A connection that goes through an SSH tunnel, a Kubernetes port-forward or an SSM session often can't be used again after the laptop sleeps or the network drops. The user has to restart Tabularis.
- #190 (open since May): MySQL over SSH is unusable after the PC sleeps. Reported on Windows, then macOS (July), and again on v0.30.0 on Windows (Oct 27): "Reconnecting from the UI does not resolve the issue consistently."
- #406: the "port already in use" part was fixed in #407 (dead tunnels now release the port and are evicted before reuse), but the recovery path is still "disconnect, then the user reconnects by hand".
- #989 (assigned to me): connect timeouts landed for PostgreSQL and MySQL in #1288. Query timeout and server-side cancel are the planned follow-up, and they belong to the same problem: a dead or stuck connection should fail fast and clearly, and never hang.
What the code does today
transport/desktop/health_check.rspings each open connection every 30 s (DEFAULT_PING_INTERVAL) with a 5 s timeout. After 2 failures (FAILURE_THRESHOLD) it callshandle_connection_failure: unregister, close every pool for the connection id, emit a failure event. Nothing tries to reconnect.- Tunnels are cached per key (
ssh_tunnel::get_tunnels,k8s_tunnel::get_tunnels,ssm_tunnel::get_tunnels). Each has anis_alive(), andapplication/tunnels.rsdiscards a dead entry before reuse. For a russh tunnel,is_alive()only turns false once the forwarding loop noticeshandle.is_closed(). After a long sleep, the TCP session can be half-open, so the tunnel still looks alive while the pool's sockets are dead. That matches the "doesn't resolve consistently" report, but I still need to reproduce it before relying on it. - The ping loop lives in the desktop transport only. Web mode (
transport/web/) has an event-stream heartbeat for the browser, but I couldn't find a database health check there.
Proposal
One connection lifecycle shared by the desktop and web transports, in src-tauri/src/application/ as AGENTS.md asks:
Connected -> Suspect (ping failed, or a wall-clock gap showed the machine slept)
Suspect -> Reconnecting (tear down this connection's pools and tunnel, rebuild once)
Reconnecting -> Connected | Lost (after N attempts with backoff)
Lost -> Reconnecting (user clicks Reconnect)
- A gap between two ticks much longer than the interval means the machine slept. That alone moves a connection to Suspect, without waiting for 2 failed pings.
- Rebuilding always drops the cached tunnel for the connection too, even when
is_alive()still says true. That handles the half-open case without guessing. - Open editor tabs, results and pending grid edits stay put. Only the pools and tunnel are replaced.
- The frontend gets one event with the state, and the connection card and status bar show "Reconnecting…" / "Connection lost, Reconnect".
- Defaults keep today's behaviour as close as possible: automatic reconnect on, with a setting to turn it off.
Phased PRs
Each phase is one PR that stands alone and ships with tests.
- Lifecycle core + sleep detection (L). State machine in
application/, wall-clock gap detection, a "drop tunnel + pools for one connection id" helper reused fromhandle_connection_failure, and one automatic reconnect attempt. Rust unit tests on the state machine. An integration test that kills the forward with the existingproxy/tcp_forward.rsand checks that the next query succeeds. - Status UI + manual Reconnect (M). Event payload, connection card and status bar states, Reconnect action, all locales.
- Query timeout + server-side cancel (L, #989 phase 2).
statement_timeouton PostgreSQL,max_execution_timefor MySQLSELECT, a client-side fallback withpg_cancel_backend/KILL QUERY, and the result panel says the query was stopped by the timeout. - Web mode parity (M). Run the same lifecycle in the Axum server and send state changes over the existing event stream.
- Kubernetes and SSM tunnels (M). Same teardown and rebuild for
k8s_tunnelandssm_tunnel, with tests for a port-forward that dies.
Open questions for maintainers
- Issue or Discussion, and should it go in
roadmap.json? - Is automatic reconnect on by default acceptable, or opt-in first?
- Plugin drivers: should phase 1 call a plugin
pingand leave reconnect to the host, or skip plugins until the plugin API has a hook? - I can test on Linux and with Windows/macOS reporters from #190. Is there anyone with a Windows machine who could check phase 1?
I'm happy to own all five phases. I'd start with phase 1 once you agree on the shape.
I use an AI coding assistant for research and code; I review and test everything I submit.
- Dominant language
- TypeScript
- Stars
- 5.1k
- Forks
- 335
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 260
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from TabularisDB/tabularis
-
[Feat]: Align the Web password login page with Tabularis designPossibly taken @Detoy claimed this today. Openfeature request
TabularisDB/tabularis#1341 · 2 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
[Bug]: OpenAI compatible provider requires API key, even when not actually required by providerPossibly taken @dyk1454683243-sudo claimed this 1 day ago. Openbug
Difficulty 3/5 1-2 days Newbie friendliness 58/100
TabularisDB/tabularis#1323 · 2 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
feature request good first issue
Difficulty 4/5 3-5 days Newbie friendliness 55/100
TabularisDB/tabularis#1314 ·
Maintainers usually reply within 1 day
-
[Feat]: Import connections from NavicatPossibly taken @fixfon claimed this today. Openfeature request good first issue
Difficulty 4/5 3-5 days Newbie friendliness 65/100
TabularisDB/tabularis#1312 ·
Maintainers usually reply within 1 day
-
[Feat]: Import connections from HeidiSQLPossibly taken @fixfon claimed this today. Openfeature request good first issue
Difficulty 4/5 3-5 days Newbie friendliness 66/100
TabularisDB/tabularis#1311 ·
Maintainers usually reply within 1 day
All issues in TabularisDB/tabularis
Similar issues
-
area:desktop area:ui bug platform:macos
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
anthropics/claude-code#106183 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
feature:App-Tour feature:Chat ready Web
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
digitalfabrik/integreat-app#4523 · 2 reactions ·
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Required Lexical field accepts two empty paragraphsPossibly taken @lazerg claimed this today. OpenBug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
payloadcms/payload#19222 ·
Maintainers usually reply within 1 day