Commit 12049d8
Add async initial connect for cursor SF sender
initial_connect_retry already had a SYNC mode that retried on the user
thread up to reconnect_max_duration_millis, but that contradicts SF's
core promise of decoupling the producer from network state: at startup
the application thread is blocked on a wire that may never come up.
This change extends initial_connect_retry with a third value, async,
which:
- Returns from Sender.fromConfig immediately. The producer thread can
call at()/atNow()/flush() right away; rows accumulate in the cursor
SF engine while the I/O thread runs the connect retry loop in the
background.
- Reuses the existing per-outage retry/backoff/cap/auth-terminal
machinery from CursorWebSocketSendLoop. fail() is refactored into a
shared connectLoop(initial, phase) helper used by both the in-flight
reconnect path (phase="reconnect") and the new attemptInitialConnect
path (phase="initial connect"). The I/O loop's first iteration now
drives initial connect when the constructor was handed a null client.
- Surfaces terminal failures (auth/upgrade reject, budget exhaustion)
through the existing SenderError dispatcher rather than throwing
from the constructor. close() still rethrows the latched terminal so
users without a custom error_handler still see the failure.
The new InitialConnectMode enum (OFF, SYNC, ASYNC) replaces the
internal boolean. The legacy initialConnectRetry(boolean) builder
method is preserved as a back-compat shim that maps false to OFF and
true to SYNC, and the config string parser accepts off/false, on/true/
sync, and async as values for initial_connect_retry.
Connectivity classification:
When the connect-retry budget exhausts, the SenderError now tags the
failure by what was actually observed on the wire so users can tell a
config typo apart from a transient blip:
- never-connected-budget-exhausted: ... -- never reached the server
(check addr/port/firewall) -- when the I/O loop has not once
installed a live, upgraded WebSocket. Most likely a typo, wrong
port, firewall block, or server not yet deployed.
- connection-lost-budget-exhausted: ... -- server unreachable since
last connect (transient) -- when the loop did connect at least
once and the wire dropped after.
A sticky volatile boolean hasEverConnected on the I/O loop tracks the
distinction; CursorWebSocketSendLoop.hasEverConnected() and
QwpWebSocketSender.wasEverConnected() expose it for handlers that want
to branch programmatically without parsing the message string. The
flag is set in the constructor for SYNC/OFF modes (which are handed a
live client) and inside swapClient on every successful connect for
ASYNC and reconnect paths.
Auth/upgrade rejects keep the existing ws-upgrade-failed message and
SECURITY_ERROR category -- the failure cause is already self-describing
and disambiguation is unnecessary.
Tests:
InitialConnectAsyncTest covers six cases:
- fromConfig returns immediately in async mode with no server reachable;
- buffered rows are delivered once a late-arriving server starts;
- never-connected budget exhaustion uses the never-connected tag and
wasEverConnected() returns false;
- 401 upgrade reject delivers SECURITY_ERROR via the inbox short of the
cap;
- connect-then-disconnect budget exhaustion uses the connection-lost
tag and wasEverConnected() remains true;
- OFF/SYNC modes report wasEverConnected()==true the moment the sender
is visible to the caller.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent fc8d8b3 commit 12049d8
4 files changed
Lines changed: 733 additions & 51 deletions
File tree
- core/src
- main/java/io/questdb/client
- cutlass/qwp/client
- sf/cursor
- test/java/io/questdb/client/test/cutlass/qwp/client
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
569 | 569 | | |
570 | 570 | | |
571 | 571 | | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
572 | 602 | | |
573 | 603 | | |
574 | 604 | | |
| |||
694 | 724 | | |
695 | 725 | | |
696 | 726 | | |
697 | | - | |
698 | | - | |
699 | | - | |
700 | | - | |
701 | | - | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
702 | 732 | | |
703 | 733 | | |
704 | 734 | | |
| |||
1112 | 1142 | | |
1113 | 1143 | | |
1114 | 1144 | | |
1115 | | - | |
| 1145 | + | |
1116 | 1146 | | |
1117 | 1147 | | |
1118 | 1148 | | |
| |||
1966 | 1996 | | |
1967 | 1997 | | |
1968 | 1998 | | |
| 1999 | + | |
| 2000 | + | |
| 2001 | + | |
| 2002 | + | |
| 2003 | + | |
1969 | 2004 | | |
1970 | 2005 | | |
1971 | 2006 | | |
1972 | 2007 | | |
1973 | 2008 | | |
1974 | | - | |
| 2009 | + | |
| 2010 | + | |
| 2011 | + | |
| 2012 | + | |
| 2013 | + | |
| 2014 | + | |
| 2015 | + | |
| 2016 | + | |
| 2017 | + | |
| 2018 | + | |
| 2019 | + | |
| 2020 | + | |
| 2021 | + | |
| 2022 | + | |
| 2023 | + | |
| 2024 | + | |
| 2025 | + | |
| 2026 | + | |
1975 | 2027 | | |
1976 | 2028 | | |
1977 | 2029 | | |
| |||
2594 | 2646 | | |
2595 | 2647 | | |
2596 | 2648 | | |
2597 | | - | |
2598 | | - | |
| 2649 | + | |
| 2650 | + | |
| 2651 | + | |
2599 | 2652 | | |
2600 | | - | |
| 2653 | + | |
| 2654 | + | |
| 2655 | + | |
2601 | 2656 | | |
2602 | | - | |
| 2657 | + | |
2603 | 2658 | | |
2604 | 2659 | | |
2605 | 2660 | | |
| |||
Lines changed: 75 additions & 26 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
182 | 182 | | |
183 | 183 | | |
184 | 184 | | |
185 | | - | |
186 | | - | |
| 185 | + | |
| 186 | + | |
187 | 187 | | |
188 | | - | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
189 | 194 | | |
190 | 195 | | |
191 | 196 | | |
| |||
361 | 366 | | |
362 | 367 | | |
363 | 368 | | |
364 | | - | |
| 369 | + | |
365 | 370 | | |
366 | 371 | | |
367 | 372 | | |
368 | | - | |
369 | | - | |
370 | | - | |
371 | | - | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
372 | 378 | | |
373 | 379 | | |
374 | 380 | | |
| |||
386 | 392 | | |
387 | 393 | | |
388 | 394 | | |
389 | | - | |
| 395 | + | |
390 | 396 | | |
391 | 397 | | |
392 | 398 | | |
393 | 399 | | |
394 | 400 | | |
395 | 401 | | |
396 | | - | |
| 402 | + | |
397 | 403 | | |
398 | 404 | | |
399 | 405 | | |
| |||
417 | 423 | | |
418 | 424 | | |
419 | 425 | | |
420 | | - | |
| 426 | + | |
421 | 427 | | |
422 | 428 | | |
423 | 429 | | |
| |||
432 | 438 | | |
433 | 439 | | |
434 | 440 | | |
435 | | - | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
436 | 444 | | |
437 | 445 | | |
438 | 446 | | |
| |||
1584 | 1592 | | |
1585 | 1593 | | |
1586 | 1594 | | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
1587 | 1609 | | |
1588 | 1610 | | |
1589 | 1611 | | |
| |||
1679 | 1701 | | |
1680 | 1702 | | |
1681 | 1703 | | |
1682 | | - | |
1683 | | - | |
1684 | | - | |
1685 | | - | |
1686 | | - | |
1687 | | - | |
1688 | | - | |
1689 | | - | |
1690 | | - | |
| 1704 | + | |
| 1705 | + | |
| 1706 | + | |
| 1707 | + | |
| 1708 | + | |
| 1709 | + | |
| 1710 | + | |
| 1711 | + | |
| 1712 | + | |
| 1713 | + | |
| 1714 | + | |
| 1715 | + | |
| 1716 | + | |
| 1717 | + | |
| 1718 | + | |
| 1719 | + | |
| 1720 | + | |
| 1721 | + | |
| 1722 | + | |
| 1723 | + | |
| 1724 | + | |
| 1725 | + | |
| 1726 | + | |
| 1727 | + | |
1691 | 1728 | | |
1692 | 1729 | | |
1693 | 1730 | | |
| |||
1708 | 1745 | | |
1709 | 1746 | | |
1710 | 1747 | | |
1711 | | - | |
1712 | | - | |
| 1748 | + | |
| 1749 | + | |
| 1750 | + | |
| 1751 | + | |
1713 | 1752 | | |
1714 | 1753 | | |
1715 | 1754 | | |
1716 | 1755 | | |
1717 | | - | |
| 1756 | + | |
| 1757 | + | |
| 1758 | + | |
| 1759 | + | |
| 1760 | + | |
| 1761 | + | |
| 1762 | + | |
| 1763 | + | |
| 1764 | + | |
| 1765 | + | |
| 1766 | + | |
| 1767 | + | |
| 1768 | + | |
1718 | 1769 | | |
1719 | 1770 | | |
1720 | 1771 | | |
| |||
1723 | 1774 | | |
1724 | 1775 | | |
1725 | 1776 | | |
1726 | | - | |
1727 | | - | |
1728 | 1777 | | |
1729 | 1778 | | |
1730 | 1779 | | |
| |||
0 commit comments