feat(app): wire AppRuntime single-task dispatcher + P0 fixes - #2
Merged
Conversation
- Add binary crates/app/src/main.rs (run_native entrypoint, tracing init) - Add crates/app/src/runtime.rs: single Tokio task draining AppCommand via spawn_blocking recv, registries for LiveSession/QueryEntry, handlers for Connect/Disconnect/Execute(limit 100)/Cancel/RefreshSchema/HistorySearch, streaming via query_raw+prepare + Box::pin(RowStream) -> spawn_drive -> SharedStore - Fix LiveSession.client to Arc<Client> (tokio-postgres 0.7.18 !Clone) and cancel_query(NoTls) - Add webpki-roots, connect_timeout+keepalives, fix bytea OID 17 handling, editing escaping, history UTF-8 truncation, prepare_session default_transaction_read_only - Fix app/lib.rs: Arc<RwLock<AppState>>, spawn runtime on Handle::try_current with exclusive cmd_rx, off-UI-thread editor persist, CompletionEngine ptr-eq cache Checks: cargo fmt, cargo check --workspace, cargo clippy --workspace --all-targets --all-features (0 errors), cargo test -p pgnative-app/db-connection/results-* 5/4/3/11 pass
With channel_cap=2 the producer would block on 3rd send if awaited before draining rx (Meta + 1st Batch fills cap, 2nd Batch awaits forever -> >60s hang). Run drive_iter concurrently via tokio::spawn and await handle after draining, asserting 5 rows / 3 batches.
…tization, stream budgets) - db/connection: cancel uses MakeRustlsConnect per SslMode (Fix CRITICAL NoTls leak) - db/execution: gate SQL logging to sql_len only (§35) - storage/history: sanitize_for_history redacts secrets, FTS5 escaping, char-boundary trunc - app/runtime: remove silent LIMIT 100 rewrite (§16), try_send everywhere (no crossbeam block) - app/runtime+db/connection: queries leak fixed via Arc<Mutex>+QGuard Drop, LiveSession abort_driver on disconnect - db/introspection: prepare_session session-scoped read-only removed (only statement_timeout) - results/stream: byte trunc finds UTF-8 boundary, preserves type on trunc - viewport: f64 precision for scroll/height; schema/build: u32::try_from for Id casts - StreamConfig: batch 64 / channel 16 (32GiB theoretical -> ~256MiB)
- runtime: replace per-command spawn_blocking churn with single
crossbeam->tokio mpsc bridge thread (1 blocking thread, 256 cap)
- runtime: Cancel marks SessionHealth::Poisoned on cancel_query failure
and aborts bridge thread on shutdown
- app: PgnativeApp::new loads ui_state off render thread via
spawn_blocking + PreferencesRestored event (no SQLite on UI thread)
- app: editor persist debounced 350ms (prevents per-keystroke thread
explosion), runtime handle stored and aborted on Drop
- schema/model: last().unwrap() -> expect("just pushed") (clippy)
C1 crates/db/connection/src/lib.rs:676 cancel_query_via_tls now returns Err(String) on build_rustls_config failure instead of falling back to NoTls; plaintext fallback would leak pid/secret on hostssl servers. C1 crates/db/cancellation/src/lib.rs:54 TokenCanceller stores SslMode + ssl_root_cert and uses build_rustls_config; Disable uses NoTls only, TLS errors map to CancelError::Failed (no plaintext fallback). C2 crates/db/connection/src/lib.rs:555 document VerifyFull/VerifyCa/ Require/Prefer trust-anchor behavior; all non-Disable modes load webpki roots and never silently accept insecure. C3 crates/storage/history/src/lib.rs:56 expand sanitize_for_history to redact api_key, apikey, private_key, aws_secret, client_secret. C4 crates/storage/editor_state/src/lib.rs:86 upsert returns early when persisted_buffers OFF (avoids persisting arbitrary SQL secrets). H1 crates/db/connection/src/lib.rs:164 sanitize_url fallback now loops per key to redact all occurrences via while let Some(idx) pattern. H4 crates/results/export/src/lib.rs:39 export_json uses serde_json::to_string for cell escaping (handles ", \n, \ etc.). H5 crates/db/connection/src/lib.rs:525 replace hand-rolled base64 with base64 crate (Engine::decode) and duplicate in cancellation crate. Verification: cargo fmt, cargo check --workspace (0 errors), cargo clippy --workspace --all-targets (0 errors), cargo test --workspace --lib (all ok).
BUG #2 crates/app/src/runtime.rs:160 — query handle race: insert placeholder QueryEntry before tokio::spawn so Cancel finds entry immediately; swap placeholder with real handle after spawn, abort new handle if entry was already removed (no leak on fast prepare error via QGuard Drop removing entry). BUG #10 crates/app/src/runtime.rs:38 — bridge thread deadlock: replace blocking_send with try_send+retry loop with 1ms backoff and is_closed check; channel cap 256 prevents flood, abort closes channel. LOW 2.1 crates/results/stream/src/lib.rs:107 — truncation end.max(1) reintroduced invalid UTF-8 at cap=1: return Bytes::new() when end==0 instead of max(1); also walk to char boundary safely. LOW 2.1 variant preservation crates/results/stream/src/lib.rs:107 — add TODO that truncated jsonb/bytea currently coerced to Text. LOW 2.3 crates/ui/results/src/lib.rs:115 — fix &b[..2048] not char boundary: floor to previous char boundary via continuation-byte walk before from_utf8_lossy. LOW 3.2 crates/results/stream/src/lib.rs:13 — reduce PER_CELL_CAP from 256KiB to 64KiB with budget comment (64MiB store, channel_cap 16). LOW 7.1 crates/results/viewport/src/lib.rs:39 — document overscan double (2×) intentional, clamp via fetch_range, clarify visible_range docs. LOW 8.1 crates/results/store/src/lib.rs:129 — add comment that parking_lot RwLock not held across await; write locks are short critical sections in push_batch/complete/cancel. Co-authored-by: opencode
…migrations Fix AppController::send_command dummy-channel drain bug by dropping retry logic that tried to recv from swapped dummy_rx; now just warns and drops command per bounded 256 contract. Annotate AppState.tx as derived from ConnectionState. Add missing FTS AFTER DELETE/UPDATE triggers (history_ad/history_au) for history_fts external content sync. Wrap each migrate version block in BEGIN/COMMIT with ROLLBACK on error to make migrations transactional. Co-Authored-By: internal-model
… extraction - edit: reject half-bound UPDATE when PK values missing/empty or mismatched; update_sql now errors without PK (no empty-string defaults), update_sql_with_pk validates pk_values len and per-column presence/emptiness - introspection: return Err on empty schemas instead of phantom Id(0) fallback; hydrate now returns Result and introspect propagates error - introspection: fix FK foreign_keys_in direction — swap referencing/referenced and referenced_relation to child (src_id) for inbound side - completion: implement FROM/JOIN alias extraction (FROM/JOIN regex hand-rolled, AS handling, reserved-word filtering) with extract_alias_map and extract_aliases_with_model - schema/cache, app: document AppState.schema duplicates SchemaCache (hot epoch) Co-authored-by: internal
…eholder Wire explorer tree from SchemaModel with search filter and columns, history panel with scrollable selectable labels, connection form grid, keyboard shortcuts (Ctrl+Enter/F5/Esc) and history typed event with back-compat, top-bar Tx badge, and export buttons. Small appends to runtime to emit HistoryResults.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See branch feat/app-runtime-wiring — pushed with fmt/check/clippy/test passing. Body in commit message.