Skip to content

Commit 38a1b24

Browse files
HandyS11claude
andcommitted
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>
1 parent 15f19de commit 38a1b24

1 file changed

Lines changed: 9 additions & 6 deletions

File tree

src/RustPlusBot.Features.Connections/Supervisor/ConnectionSupervisor.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -558,9 +558,6 @@ void OnTeamMessage(object? sender, TeamChatLine line)
558558
}
559559
#pragma warning restore RCS1163
560560

561-
var dims = await connection.GetMapDimensionsAsync(_options.HeartbeatTimeout, ct).ConfigureAwait(false);
562-
var rigs = await GetRigPositionsAsync(key.Server, connection, ct).ConfigureAwait(false);
563-
564561
#pragma warning disable RCS1163 // Unused 'sender': required by the EventHandler<SmartDeviceTrigger> delegate shape.
565562
void OnSmartDevice(object? sender, SmartDeviceTrigger trigger)
566563
{
@@ -607,7 +604,7 @@ void OnClanChanged(object? sender, ClanProbeResult probe)
607604
await PublishClanStateAsync(key, clanProbe).ConfigureAwait(false);
608605

609606
using var pollCts = CancellationTokenSource.CreateLinkedTokenSource(ct);
610-
var markerPoll = Task.Run(() => PollMarkersAsync(key, connection, dims, rigs, tracker, pollCts.Token),
607+
var markerPoll = Task.Run(() => PollMarkersAsync(key, connection, tracker, pollCts.Token),
611608
CancellationToken.None);
612609
var reachabilityPoll = Task.Run(() => PollReachabilityAsync(key, connection, pollCts.Token),
613610
CancellationToken.None);
@@ -703,11 +700,17 @@ await PublishStatusAsync(key, ConnectionStatus.Connected, beat.PlayerCount, cred
703700
private async Task PollMarkersAsync(
704701
(ulong Guild, Guid Server) key,
705702
IRustServerConnection connection,
706-
MapDimensions? dims,
707-
IReadOnlyList<RigPosition> rigs,
708703
TeamStateTracker tracker,
709704
CancellationToken ct)
710705
{
706+
// Fetch map dimensions and oil-rig positions here, off the critical connect path: these are the two
707+
// heavy full-map downloads, and on a degraded map endpoint they can stall for seconds. Doing them in
708+
// this background poll means a slow map no longer delays the connection going live (heartbeat + chat
709+
// relay start immediately); marker/rig detection simply activates once these resolve. Both degrade
710+
// safely on timeout (dims -> null, rigs -> empty) without ending the poll.
711+
var dims = await connection.GetMapDimensionsAsync(_options.HeartbeatTimeout, ct).ConfigureAwait(false);
712+
var rigs = await GetRigPositionsAsync(key.Server, connection, ct).ConfigureAwait(false);
713+
711714
IReadOnlyList<MapMarkerSnapshot>? previous = null;
712715
var rigsInRadius = new HashSet<RigKind>();
713716
while (!ct.IsCancellationRequested)

0 commit comments

Comments
 (0)