Commit 2ffb18f
fix(connections): survive transient map-endpoint timeouts (no more permanent connection death) (#63)
* fix(connections): stop a transient request timeout from killing the connection loop
A per-request timeout during a connected window surfaces as an
OperationCanceledException even when the connection token is NOT cancelled.
GetRigPositionsAsync rethrew it unconditionally and RunAsync treats any OCE as
a shutdown signal, so a transient slow map endpoint permanently terminated the
per-server connection loop with no reconnect (bot connected, dropped ~20s later,
then went silent). Confirmed via a live repro trace.
Guard the timeout catches with `when (ct.IsCancellationRequested)` in
GetRigPositionsAsync, PollMarkersAsync and PollReachabilityAsync so a request
timeout degrades that one window instead of tearing down the connection, and add
the missing `.WaitAsync` timeout guard to GetClanInfoAsync (the one connect-time
probe that could block indefinitely on a dead socket).
Regression test: Connect_MonumentsTimeout_DoesNotKillLoop_AndStillReconnects.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(connections): detect server-initiated socket drops with a liveness watchdog
The Rust+ library raises no event when the server closes the socket, so a silent
drop previously went unnoticed until the next heartbeat (up to HeartbeatInterval,
default 60s) — a long window of a dead-but-"connected" socket.
Add IsConnected to IRustServerConnection (backed by RustPlusSocket.IsConnected)
and a WatchLivenessAsync watchdog that races the heartbeat loop and returns
Unreachable as soon as the socket is no longer open, bounded by the new
ConnectionOptions.LivenessPollInterval (default 5s).
Test: ServerClosesSocket_LivenessWatchdog_DrivesReconnect (heartbeat keeps
answering Ok, so only the watchdog can detect the drop).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* perf(connections): move the heavy map fetch off the critical connect path
GetMapDimensions and GetRigPositions (the two full-map downloads) ran on the
connect path before the heartbeat/marker loops started, so a slow or degraded
map endpoint delayed the whole connection going live — and its stalls were the
trigger for the drop that used to kill the loop.
Fetch dims + rig positions at the start of PollMarkersAsync instead. The
connection now goes live immediately (heartbeat + chat relay), and marker/rig
detection activates once the map resolves; a map timeout just disables rig
detection for that window (dims -> null, rigs -> empty) without blocking anything.
Verified live against a degraded map endpoint: clan probe now lands ~1s after
connect (was blocked ~15s behind the map fetch), and the monuments/marker
timeouts degrade in the background with the connection staying fully alive.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* style(connections): satisfy member ordering for IsConnected
The pre-push formatter relocates the IsConnected member added with the liveness
watchdog (property after the constructor / in declared order). No behavior change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(connections): apply PR review feedback
- WatchLivenessAsync now catches the cancellation OperationCanceledException and
returns ReconnectReason.Stopped, so on shutdown the WhenAny winner is a clean
reason instead of a faulted task (its doc already advertised Stopped).
- Reword the fake's monuments-timeout helpers/test: the rig/monuments fetch runs
in the background marker poll now, not on the connect path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent c6ad400 commit 2ffb18f
6 files changed
Lines changed: 186 additions & 17 deletions
File tree
- src/RustPlusBot.Features.Connections
- Listening
- Supervisor
- tests/RustPlusBot.Features.Connections.Tests
- Fakes
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
47 | 54 | | |
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
8 | 15 | | |
9 | 16 | | |
10 | 17 | | |
| |||
Lines changed: 11 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
| 38 | + | |
37 | 39 | | |
38 | 40 | | |
39 | 41 | | |
| |||
170 | 172 | | |
171 | 173 | | |
172 | 174 | | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
173 | 180 | | |
174 | 181 | | |
175 | 182 | | |
| |||
380 | 387 | | |
381 | 388 | | |
382 | 389 | | |
383 | | - | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
384 | 394 | | |
385 | 395 | | |
386 | 396 | | |
| |||
Lines changed: 73 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
558 | 558 | | |
559 | 559 | | |
560 | 560 | | |
561 | | - | |
562 | | - | |
563 | | - | |
564 | 561 | | |
565 | 562 | | |
566 | 563 | | |
| |||
607 | 604 | | |
608 | 605 | | |
609 | 606 | | |
610 | | - | |
| 607 | + | |
611 | 608 | | |
612 | 609 | | |
613 | 610 | | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
614 | 616 | | |
615 | 617 | | |
616 | | - | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
617 | 622 | | |
618 | 623 | | |
619 | 624 | | |
620 | 625 | | |
621 | 626 | | |
622 | 627 | | |
623 | | - | |
624 | | - | |
| 628 | + | |
| 629 | + | |
625 | 630 | | |
626 | 631 | | |
627 | 632 | | |
| |||
638 | 643 | | |
639 | 644 | | |
640 | 645 | | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
641 | 682 | | |
642 | 683 | | |
643 | 684 | | |
| |||
667 | 708 | | |
668 | 709 | | |
669 | 710 | | |
670 | | - | |
671 | | - | |
672 | 711 | | |
673 | 712 | | |
674 | 713 | | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
675 | 722 | | |
676 | 723 | | |
677 | 724 | | |
| |||
703 | 750 | | |
704 | 751 | | |
705 | 752 | | |
706 | | - | |
| 753 | + | |
707 | 754 | | |
708 | 755 | | |
709 | 756 | | |
710 | | - | |
| 757 | + | |
711 | 758 | | |
712 | 759 | | |
713 | 760 | | |
| 761 | + | |
| 762 | + | |
714 | 763 | | |
715 | 764 | | |
716 | 765 | | |
| |||
767 | 816 | | |
768 | 817 | | |
769 | 818 | | |
770 | | - | |
| 819 | + | |
771 | 820 | | |
772 | 821 | | |
773 | 822 | | |
774 | | - | |
| 823 | + | |
775 | 824 | | |
776 | 825 | | |
777 | 826 | | |
| 827 | + | |
| 828 | + | |
778 | 829 | | |
779 | 830 | | |
780 | 831 | | |
| |||
942 | 993 | | |
943 | 994 | | |
944 | 995 | | |
945 | | - | |
| 996 | + | |
946 | 997 | | |
| 998 | + | |
947 | 999 | | |
948 | 1000 | | |
949 | | - | |
| 1001 | + | |
950 | 1002 | | |
951 | 1003 | | |
952 | 1004 | | |
| 1005 | + | |
| 1006 | + | |
953 | 1007 | | |
954 | 1008 | | |
955 | 1009 | | |
| |||
1435 | 1489 | | |
1436 | 1490 | | |
1437 | 1491 | | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
1438 | 1496 | | |
1439 | 1497 | | |
1440 | 1498 | | |
| |||
Lines changed: 63 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| 70 | + | |
70 | 71 | | |
71 | 72 | | |
72 | 73 | | |
| |||
231 | 232 | | |
232 | 233 | | |
233 | 234 | | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
234 | 297 | | |
235 | 298 | | |
236 | 299 | | |
| |||
0 commit comments