chore: continue porting code and adding test coverage

This commit is contained in:
Stevan Freeborn
2025-05-08 01:36:04 -05:00
parent 3f4ab165ce
commit 9f35394528
12 changed files with 305 additions and 9 deletions
@@ -1,6 +1,6 @@
namespace StevesBot.Worker.Discord;
internal class DiscordClientException : Exception
internal sealed class DiscordClientException : Exception
{
public DiscordClientException()
{
@@ -1,8 +1,8 @@
namespace StevesBot.Worker.Discord;
internal class DiscordClientOptions
internal sealed class DiscordClientOptions
{
public string ApiUrl { get; init; } = string.Empty;
public string AppToken { get; init; } = string.Empty;
public int Intents { get; init; }
}
}
@@ -3,7 +3,7 @@ namespace StevesBot.Worker.Discord.Events;
internal record DiscordEvent
{
[JsonPropertyName("op")]
public int Op { get; init; }
public int OpCode { get; init; }
[JsonPropertyName("s")]
public int? Sequence { get; init; }
@@ -1,6 +1,6 @@
namespace StevesBot.Worker.Discord.Events;
internal class DiscordEventConverter : JsonConverter<DiscordEvent>
internal sealed class DiscordEventConverter : JsonConverter<DiscordEvent>
{
private const string OpPropertyName = "op";
@@ -1,13 +1,13 @@
namespace StevesBot.Worker.Discord.Events;
internal record HelloDiscordEvent : DiscordEvent
internal sealed record HelloDiscordEvent : DiscordEvent
{
[JsonPropertyName("d")]
public new HelloData? Data { get; init; }
}
internal record HelloData
internal sealed record HelloData
{
[JsonPropertyName("heartbeat_interval")]
public int HeartbeatInterval { get; init; }
}
}
@@ -0,0 +1,24 @@
namespace StevesBot.Worker.Threading;
internal sealed class AsyncLock : IAsyncLock
{
private readonly SemaphoreSlim _semaphore = new(1, 1);
private bool _disposed;
public async Task<IDisposable> LockAsync(CancellationToken cancellationToken = default)
{
await _semaphore.WaitAsync(cancellationToken);
return new LockReleaser(_semaphore);
}
public void Dispose()
{
if (_disposed)
{
return;
}
_semaphore.Dispose();
_disposed = true;
}
}
@@ -0,0 +1,6 @@
namespace StevesBot.Worker.Threading;
internal interface IAsyncLock : IDisposable
{
Task<IDisposable> LockAsync(CancellationToken cancellationToken = default);
}
@@ -0,0 +1,23 @@
namespace StevesBot.Worker.Threading;
internal sealed class LockReleaser : IDisposable
{
private readonly SemaphoreSlim _semaphore;
private bool _released;
public LockReleaser(SemaphoreSlim semaphore)
{
_semaphore = semaphore;
}
public void Dispose()
{
if (_released)
{
return;
}
_semaphore.Release();
_released = true;
}
}