chore: continue porting code and adding test coverage
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user