Skip to content

Commit 0555754

Browse files
HandyS11claude
andcommitted
feat(workspace): refresh #info on ServerCredentialsChangedEvent
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1da31ae commit 0555754

2 files changed

Lines changed: 59 additions & 1 deletion

File tree

src/RustPlusBot.Features.Workspace/Hosting/WorkspaceHostedService.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ internal sealed class WorkspaceHostedService(
2121
{
2222
private readonly CancellationTokenSource _cts = new();
2323
private Task? _connectionStatusLoop;
24+
private Task? _serverCredentialsLoop;
2425
private Task? _serverRegisteredLoop;
2526
private bool _startupDone;
2627

@@ -34,6 +35,7 @@ public Task StartAsync(CancellationToken cancellationToken)
3435
client.ChannelDestroyed += OnChannelDestroyedAsync;
3536
_serverRegisteredLoop = Task.Run(() => ConsumeServerRegisteredAsync(_cts.Token), CancellationToken.None);
3637
_connectionStatusLoop = Task.Run(() => ConsumeConnectionStatusAsync(_cts.Token), CancellationToken.None);
38+
_serverCredentialsLoop = Task.Run(() => ConsumeServerCredentialsAsync(_cts.Token), CancellationToken.None);
3739
return Task.CompletedTask;
3840
}
3941

@@ -45,7 +47,7 @@ public async Task StopAsync(CancellationToken cancellationToken)
4547
await _cts.CancelAsync().ConfigureAwait(false);
4648
foreach (var loop in new[]
4749
{
48-
_serverRegisteredLoop, _connectionStatusLoop
50+
_serverRegisteredLoop, _connectionStatusLoop, _serverCredentialsLoop
4951
})
5052
{
5153
if (loop is null)
@@ -136,6 +138,32 @@ await reconciler.ReconcileServerAsync(changed.GuildId, changed.ServerId, cancell
136138
}
137139
}
138140

141+
private async Task ConsumeServerCredentialsAsync(CancellationToken cancellationToken)
142+
{
143+
try
144+
{
145+
await foreach (var changed in eventBus.SubscribeAsync<ServerCredentialsChangedEvent>(cancellationToken)
146+
.ConfigureAwait(false))
147+
{
148+
var scope = scopeFactory.CreateAsyncScope();
149+
await using (scope.ConfigureAwait(false))
150+
{
151+
var reconciler = scope.ServiceProvider.GetRequiredService<IWorkspaceReconciler>();
152+
await reconciler.ReconcileServerAsync(changed.GuildId, changed.ServerId, cancellationToken)
153+
.ConfigureAwait(false);
154+
}
155+
}
156+
}
157+
catch (OperationCanceledException)
158+
{
159+
// Shutting down.
160+
}
161+
catch (Exception ex) // Broad catch is intentional: a faulting consumer must not crash the host.
162+
{
163+
logger.LogError(ex, "ServerCredentialsChanged consumer faulted.");
164+
}
165+
}
166+
139167
private async Task ConsumeServerRegisteredAsync(CancellationToken cancellationToken)
140168
{
141169
// Subscription is registered when this loop first calls SubscribeAsync; the in-process bus does

tests/RustPlusBot.Features.Workspace.Tests/Hosting/WorkspaceConnectionStatusTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,34 @@ public async Task ConnectionStatusChanged_ReconcilesThatServer()
4040

4141
await service.StopAsync(default);
4242
}
43+
44+
[Fact]
45+
public async Task ServerCredentialsChanged_ReconcilesThatServer()
46+
{
47+
var reconciler = Substitute.For<IWorkspaceReconciler>();
48+
var services = new ServiceCollection();
49+
services.AddScoped(_ => reconciler);
50+
await using var provider = services.BuildServiceProvider();
51+
52+
var bus = new InMemoryEventBus();
53+
var client = new DiscordSocketClient();
54+
var service = new WorkspaceHostedService(client, bus,
55+
provider.GetRequiredService<IServiceScopeFactory>(),
56+
NullLogger<WorkspaceHostedService>.Instance);
57+
58+
await service.StartAsync(default);
59+
var serverId = Guid.NewGuid();
60+
var deadline = DateTimeOffset.UtcNow.AddSeconds(20);
61+
while (DateTimeOffset.UtcNow < deadline
62+
&& !reconciler.ReceivedCalls().Any(c =>
63+
c.GetMethodInfo().Name == nameof(IWorkspaceReconciler.ReconcileServerAsync)))
64+
{
65+
await bus.PublishAsync(new ServerCredentialsChangedEvent(10UL, serverId));
66+
await Task.Delay(20);
67+
}
68+
69+
await reconciler.Received().ReconcileServerAsync(10UL, serverId, Arg.Any<CancellationToken>());
70+
71+
await service.StopAsync(default);
72+
}
4373
}

0 commit comments

Comments
 (0)