mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2025-05-01 00:34:07 +02:00
Fix Rider inspections
This commit is contained in:
parent
137a2a53c3
commit
c7b57fac97
Common
Phantom.Common.Data.Web
Phantom.Common.Data
Controller
Utils
Phantom.Utils.Actor/Mailbox
Phantom.Utils.Rpc/Runtime
Phantom.Utils.Tests/Runtime
Phantom.Utils
Collections
Tasks
Threading
@ -7,7 +7,7 @@ public enum EventLogEventType {
|
|||||||
InstanceStopped,
|
InstanceStopped,
|
||||||
InstanceBackupSucceeded,
|
InstanceBackupSucceeded,
|
||||||
InstanceBackupSucceededWithWarnings,
|
InstanceBackupSucceededWithWarnings,
|
||||||
InstanceBackupFailed,
|
InstanceBackupFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EventLogEventTypeExtensions {
|
public static class EventLogEventTypeExtensions {
|
||||||
@ -18,7 +18,7 @@ public static class EventLogEventTypeExtensions {
|
|||||||
{ EventLogEventType.InstanceStopped, EventLogSubjectType.Instance },
|
{ EventLogEventType.InstanceStopped, EventLogSubjectType.Instance },
|
||||||
{ EventLogEventType.InstanceBackupSucceeded, EventLogSubjectType.Instance },
|
{ EventLogEventType.InstanceBackupSucceeded, EventLogSubjectType.Instance },
|
||||||
{ EventLogEventType.InstanceBackupSucceededWithWarnings, EventLogSubjectType.Instance },
|
{ EventLogEventType.InstanceBackupSucceededWithWarnings, EventLogSubjectType.Instance },
|
||||||
{ EventLogEventType.InstanceBackupFailed, EventLogSubjectType.Instance },
|
{ EventLogEventType.InstanceBackupFailed, EventLogSubjectType.Instance }
|
||||||
};
|
};
|
||||||
|
|
||||||
static EventLogEventTypeExtensions() {
|
static EventLogEventTypeExtensions() {
|
||||||
|
@ -4,7 +4,7 @@ using MemoryPack;
|
|||||||
namespace Phantom.Common.Data.Web.Users;
|
namespace Phantom.Common.Data.Web.Users;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record LogInSuccess (
|
public sealed partial record LogInSuccess(
|
||||||
[property: MemoryPackOrder(0)] Guid UserGuid,
|
[property: MemoryPackOrder(0)] Guid UserGuid,
|
||||||
[property: MemoryPackOrder(1)] PermissionSet Permissions,
|
[property: MemoryPackOrder(1)] PermissionSet Permissions,
|
||||||
[property: MemoryPackOrder(2)] ImmutableArray<byte> Token
|
[property: MemoryPackOrder(2)] ImmutableArray<byte> Token
|
||||||
|
@ -14,9 +14,7 @@ public sealed partial class AuthToken {
|
|||||||
private readonly byte[] bytes;
|
private readonly byte[] bytes;
|
||||||
|
|
||||||
internal AuthToken(byte[]? bytes) {
|
internal AuthToken(byte[]? bytes) {
|
||||||
if (bytes == null) {
|
ArgumentNullException.ThrowIfNull(bytes);
|
||||||
throw new ArgumentNullException(nameof(bytes));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytes.Length != Length) {
|
if (bytes.Length != Length) {
|
||||||
throw new ArgumentOutOfRangeException(nameof(bytes), "Invalid token length: " + bytes.Length + ". Token length must be exactly " + Length + " bytes.");
|
throw new ArgumentOutOfRangeException(nameof(bytes), "Invalid token length: " + bytes.Length + ". Token length must be exactly " + Length + " bytes.");
|
||||||
|
@ -13,18 +13,18 @@ namespace Phantom.Controller.Database;
|
|||||||
|
|
||||||
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
||||||
public class ApplicationDbContext : DbContext {
|
public class ApplicationDbContext : DbContext {
|
||||||
public DbSet<UserEntity> Users { get; set; } = null!;
|
public DbSet<UserEntity> Users { get; init; } = null!;
|
||||||
public DbSet<RoleEntity> Roles { get; set; } = null!;
|
public DbSet<RoleEntity> Roles { get; init; } = null!;
|
||||||
public DbSet<PermissionEntity> Permissions { get; set; } = null!;
|
public DbSet<PermissionEntity> Permissions { get; init; } = null!;
|
||||||
|
|
||||||
public DbSet<UserRoleEntity> UserRoles { get; set; } = null!;
|
public DbSet<UserRoleEntity> UserRoles { get; init; } = null!;
|
||||||
public DbSet<UserPermissionEntity> UserPermissions { get; set; } = null!;
|
public DbSet<UserPermissionEntity> UserPermissions { get; init; } = null!;
|
||||||
public DbSet<RolePermissionEntity> RolePermissions { get; set; } = null!;
|
public DbSet<RolePermissionEntity> RolePermissions { get; init; } = null!;
|
||||||
|
|
||||||
public DbSet<AgentEntity> Agents { get; set; } = null!;
|
public DbSet<AgentEntity> Agents { get; init; } = null!;
|
||||||
public DbSet<InstanceEntity> Instances { get; set; } = null!;
|
public DbSet<InstanceEntity> Instances { get; init; } = null!;
|
||||||
public DbSet<AuditLogEntity> AuditLog { get; set; } = null!;
|
public DbSet<AuditLogEntity> AuditLog { get; init; } = null!;
|
||||||
public DbSet<EventLogEntity> EventLog { get; set; } = null!;
|
public DbSet<EventLogEntity> EventLog { get; init; } = null!;
|
||||||
|
|
||||||
public AgentEntityUpsert AgentUpsert { get; }
|
public AgentEntityUpsert AgentUpsert { get; }
|
||||||
public InstanceEntityUpsert InstanceUpsert { get; }
|
public InstanceEntityUpsert InstanceUpsert { get; }
|
||||||
|
@ -9,7 +9,7 @@ namespace Phantom.Controller.Database.Entities;
|
|||||||
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
||||||
public sealed class AgentEntity {
|
public sealed class AgentEntity {
|
||||||
[Key]
|
[Key]
|
||||||
public Guid AgentGuid { get; set; }
|
public Guid AgentGuid { get; init; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public ushort ProtocolVersion { get; set; }
|
public ushort ProtocolVersion { get; set; }
|
||||||
|
@ -13,16 +13,16 @@ public class AuditLogEntity : IDisposable {
|
|||||||
[Key]
|
[Key]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
public long Id { get; set; }
|
public long Id { get; init; }
|
||||||
|
|
||||||
public Guid? UserGuid { get; set; }
|
public Guid? UserGuid { get; init; }
|
||||||
public DateTime UtcTime { get; set; } // Note: Converting to UTC is not best practice, but for historical records it's good enough.
|
public DateTime UtcTime { get; init; } // Note: Converting to UTC is not best practice, but for historical records it's good enough.
|
||||||
public AuditLogEventType EventType { get; set; }
|
public AuditLogEventType EventType { get; init; }
|
||||||
public AuditLogSubjectType SubjectType { get; set; }
|
public AuditLogSubjectType SubjectType { get; init; }
|
||||||
public string SubjectId { get; set; }
|
public string SubjectId { get; init; }
|
||||||
public JsonDocument? Data { get; set; }
|
public JsonDocument? Data { get; init; }
|
||||||
|
|
||||||
public virtual UserEntity? User { get; set; }
|
public virtual UserEntity? User { get; init; }
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
internal AuditLogEntity() {
|
internal AuditLogEntity() {
|
||||||
|
@ -11,14 +11,14 @@ namespace Phantom.Controller.Database.Entities;
|
|||||||
[SuppressMessage("ReSharper", "ClassWithVirtualMembersNeverInherited.Global")]
|
[SuppressMessage("ReSharper", "ClassWithVirtualMembersNeverInherited.Global")]
|
||||||
public sealed class EventLogEntity : IDisposable {
|
public sealed class EventLogEntity : IDisposable {
|
||||||
[Key]
|
[Key]
|
||||||
public Guid EventGuid { get; set; }
|
public Guid EventGuid { get; init; }
|
||||||
|
|
||||||
public DateTime UtcTime { get; set; } // Note: Converting to UTC is not best practice, but for historical records it's good enough.
|
public DateTime UtcTime { get; init; } // Note: Converting to UTC is not best practice, but for historical records it's good enough.
|
||||||
public Guid? AgentGuid { get; set; }
|
public Guid? AgentGuid { get; init; }
|
||||||
public EventLogEventType EventType { get; set; }
|
public EventLogEventType EventType { get; init; }
|
||||||
public EventLogSubjectType SubjectType { get; set; }
|
public EventLogSubjectType SubjectType { get; init; }
|
||||||
public string SubjectId { get; set; }
|
public string SubjectId { get; init; }
|
||||||
public JsonDocument? Data { get; set; }
|
public JsonDocument? Data { get; init; }
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
internal EventLogEntity() {
|
internal EventLogEntity() {
|
||||||
|
@ -11,7 +11,7 @@ namespace Phantom.Controller.Database.Entities;
|
|||||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||||
public sealed class InstanceEntity {
|
public sealed class InstanceEntity {
|
||||||
[Key]
|
[Key]
|
||||||
public Guid InstanceGuid { get; set; }
|
public Guid InstanceGuid { get; init; }
|
||||||
|
|
||||||
public Guid AgentGuid { get; set; }
|
public Guid AgentGuid { get; set; }
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ namespace Phantom.Controller.Database.Entities;
|
|||||||
[Table("Permissions", Schema = "identity")]
|
[Table("Permissions", Schema = "identity")]
|
||||||
public sealed class PermissionEntity {
|
public sealed class PermissionEntity {
|
||||||
[Key]
|
[Key]
|
||||||
public string Id { get; set; }
|
public string Id { get; init; }
|
||||||
|
|
||||||
public PermissionEntity(string id) {
|
public PermissionEntity(string id) {
|
||||||
Id = id;
|
Id = id;
|
||||||
|
@ -7,9 +7,9 @@ namespace Phantom.Controller.Database.Entities;
|
|||||||
[Table("Roles", Schema = "identity")]
|
[Table("Roles", Schema = "identity")]
|
||||||
public sealed class RoleEntity {
|
public sealed class RoleEntity {
|
||||||
[Key]
|
[Key]
|
||||||
public Guid RoleGuid { get; set; }
|
public Guid RoleGuid { get; init; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; init; }
|
||||||
|
|
||||||
public RoleEntity(Guid roleGuid, string name) {
|
public RoleEntity(Guid roleGuid, string name) {
|
||||||
RoleGuid = roleGuid;
|
RoleGuid = roleGuid;
|
||||||
|
@ -4,8 +4,8 @@ namespace Phantom.Controller.Database.Entities;
|
|||||||
|
|
||||||
[Table("RolePermissions", Schema = "identity")]
|
[Table("RolePermissions", Schema = "identity")]
|
||||||
public sealed class RolePermissionEntity {
|
public sealed class RolePermissionEntity {
|
||||||
public Guid RoleGuid { get; set; }
|
public Guid RoleGuid { get; init; }
|
||||||
public string PermissionId { get; set; }
|
public string PermissionId { get; init; }
|
||||||
|
|
||||||
public RolePermissionEntity(Guid roleGuid, string permissionId) {
|
public RolePermissionEntity(Guid roleGuid, string permissionId) {
|
||||||
RoleGuid = roleGuid;
|
RoleGuid = roleGuid;
|
||||||
|
@ -7,9 +7,9 @@ namespace Phantom.Controller.Database.Entities;
|
|||||||
[Table("Users", Schema = "identity")]
|
[Table("Users", Schema = "identity")]
|
||||||
public sealed class UserEntity {
|
public sealed class UserEntity {
|
||||||
[Key]
|
[Key]
|
||||||
public Guid UserGuid { get; set; }
|
public Guid UserGuid { get; init; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; init; }
|
||||||
public string PasswordHash { get; set; }
|
public string PasswordHash { get; set; }
|
||||||
|
|
||||||
public UserEntity(Guid userGuid, string name, string passwordHash) {
|
public UserEntity(Guid userGuid, string name, string passwordHash) {
|
||||||
|
@ -4,8 +4,8 @@ namespace Phantom.Controller.Database.Entities;
|
|||||||
|
|
||||||
[Table("UserPermissions", Schema = "identity")]
|
[Table("UserPermissions", Schema = "identity")]
|
||||||
public sealed class UserPermissionEntity {
|
public sealed class UserPermissionEntity {
|
||||||
public Guid UserGuid { get; set; }
|
public Guid UserGuid { get; init; }
|
||||||
public string PermissionId { get; set; }
|
public string PermissionId { get; init; }
|
||||||
|
|
||||||
public UserPermissionEntity(Guid userGuid, string permissionId) {
|
public UserPermissionEntity(Guid userGuid, string permissionId) {
|
||||||
UserGuid = userGuid;
|
UserGuid = userGuid;
|
||||||
|
@ -4,11 +4,11 @@ namespace Phantom.Controller.Database.Entities;
|
|||||||
|
|
||||||
[Table("UserRoles", Schema = "identity")]
|
[Table("UserRoles", Schema = "identity")]
|
||||||
public sealed class UserRoleEntity {
|
public sealed class UserRoleEntity {
|
||||||
public Guid UserGuid { get; set; }
|
public Guid UserGuid { get; init; }
|
||||||
public Guid RoleGuid { get; set; }
|
public Guid RoleGuid { get; init; }
|
||||||
|
|
||||||
public UserEntity User { get; set; }
|
public UserEntity User { get; init; }
|
||||||
public RoleEntity Role { get; set; }
|
public RoleEntity Role { get; init; }
|
||||||
|
|
||||||
public UserRoleEntity(Guid userGuid, Guid roleGuid) {
|
public UserRoleEntity(Guid userGuid, Guid roleGuid) {
|
||||||
UserGuid = userGuid;
|
UserGuid = userGuid;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Akka.Actor;
|
using Phantom.Common.Data.Replies;
|
||||||
using Phantom.Common.Data.Replies;
|
|
||||||
using Phantom.Common.Messages.Agent;
|
using Phantom.Common.Messages.Agent;
|
||||||
using Phantom.Common.Messages.Agent.BiDirectional;
|
using Phantom.Common.Messages.Agent.BiDirectional;
|
||||||
using Phantom.Common.Messages.Agent.ToAgent;
|
using Phantom.Common.Messages.Agent.ToAgent;
|
||||||
@ -19,8 +18,6 @@ sealed class AgentMessageHandlerActor : ReceiveActor<IMessageToController> {
|
|||||||
return Props<IMessageToController>.Create(() => new AgentMessageHandlerActor(init), new ActorConfiguration { SupervisorStrategy = SupervisorStrategies.Resume });
|
return Props<IMessageToController>.Create(() => new AgentMessageHandlerActor(init), new ActorConfiguration { SupervisorStrategy = SupervisorStrategies.Resume });
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStash Stash { get; set; } = null!;
|
|
||||||
|
|
||||||
private readonly Guid agentGuid;
|
private readonly Guid agentGuid;
|
||||||
private readonly RpcConnectionToClient<IMessageToAgent> connection;
|
private readonly RpcConnectionToClient<IMessageToAgent> connection;
|
||||||
private readonly AgentRegistrationHandler agentRegistrationHandler;
|
private readonly AgentRegistrationHandler agentRegistrationHandler;
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
using Akka.Actor;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Akka.Actor;
|
||||||
using Akka.Configuration;
|
using Akka.Configuration;
|
||||||
using Akka.Dispatch;
|
using Akka.Dispatch;
|
||||||
using Akka.Dispatch.MessageQueues;
|
using Akka.Dispatch.MessageQueues;
|
||||||
|
|
||||||
namespace Phantom.Utils.Actor.Mailbox;
|
namespace Phantom.Utils.Actor.Mailbox;
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||||
public sealed class UnboundedJumpAheadMailbox : MailboxType, IProducesMessageQueue<UnboundedJumpAheadMessageQueue> {
|
public sealed class UnboundedJumpAheadMailbox : MailboxType, IProducesMessageQueue<UnboundedJumpAheadMessageQueue> {
|
||||||
public const string Name = "unbounded-jump-ahead-mailbox";
|
public const string Name = "unbounded-jump-ahead-mailbox";
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ public sealed class RpcConnectionToClient<TMessageBase> : RpcConnection<TMessage
|
|||||||
private readonly uint routingId;
|
private readonly uint routingId;
|
||||||
|
|
||||||
internal event EventHandler<RpcClientConnectionClosedEventArgs>? Closed;
|
internal event EventHandler<RpcClientConnectionClosedEventArgs>? Closed;
|
||||||
public bool IsClosed { get; private set; }
|
private bool isClosed;
|
||||||
|
|
||||||
internal RpcConnectionToClient(ServerSocket socket, uint routingId, MessageRegistry<TMessageBase> messageRegistry, MessageReplyTracker replyTracker) : base(messageRegistry, replyTracker) {
|
internal RpcConnectionToClient(ServerSocket socket, uint routingId, MessageRegistry<TMessageBase> messageRegistry, MessageReplyTracker replyTracker) : base(messageRegistry, replyTracker) {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
@ -24,8 +24,8 @@ public sealed class RpcConnectionToClient<TMessageBase> : RpcConnection<TMessage
|
|||||||
bool hasClosed = false;
|
bool hasClosed = false;
|
||||||
|
|
||||||
lock (this) {
|
lock (this) {
|
||||||
if (!IsClosed) {
|
if (!isClosed) {
|
||||||
IsClosed = true;
|
isClosed = true;
|
||||||
hasClosed = true;
|
hasClosed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ public class EnvironmentVariablesTests {
|
|||||||
private readonly HashSet<string> createdVariables = new ();
|
private readonly HashSet<string> createdVariables = new ();
|
||||||
|
|
||||||
private static void Discard<T>(T value) {
|
private static void Discard<T>(T value) {
|
||||||
var _ = value;
|
_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CreateVariable(string value) {
|
private string CreateVariable(string value) {
|
||||||
|
@ -1,18 +1,8 @@
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Phantom.Utils.Collections;
|
namespace Phantom.Utils.Collections;
|
||||||
|
|
||||||
public static class EnumerableExtensions {
|
public static class EnumerableExtensions {
|
||||||
[SuppressMessage("ReSharper", "LoopCanBeConvertedToQuery")]
|
|
||||||
public static IEnumerable<TSource> WhereNotNull<TSource>(this IEnumerable<TSource?> items) {
|
|
||||||
foreach (var item in items) {
|
|
||||||
if (item is not null) {
|
|
||||||
yield return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<ImmutableArray<TSource>> ToImmutableArrayAsync<TSource>(this IAsyncEnumerable<TSource> source, CancellationToken cancellationToken = default) {
|
public static async Task<ImmutableArray<TSource>> ToImmutableArrayAsync<TSource>(this IAsyncEnumerable<TSource> source, CancellationToken cancellationToken = default) {
|
||||||
var builder = ImmutableArray.CreateBuilder<TSource>();
|
var builder = ImmutableArray.CreateBuilder<TSource>();
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
namespace Phantom.Utils.Collections;
|
namespace Phantom.Utils.Collections;
|
||||||
|
|
||||||
public sealed class TableData<TRow, TKey> : IReadOnlyList<TRow>, IReadOnlyDictionary<TKey, TRow> where TRow : notnull where TKey : notnull {
|
public sealed class TableData<TRow, TKey> : IReadOnlyList<TRow>, IReadOnlyDictionary<TKey, TRow> where TRow : notnull where TKey : notnull {
|
||||||
private readonly List<TRow> rowList = new();
|
private readonly List<TRow> rowList = new ();
|
||||||
private readonly Dictionary<TKey, TRow> rowDictionary = new ();
|
private readonly Dictionary<TKey, TRow> rowDictionary = new ();
|
||||||
|
|
||||||
public TRow this[int index] => rowList[index];
|
public TRow this[int index] => rowList[index];
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Phantom.Utils.Tasks;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Phantom.Utils.Tasks;
|
||||||
|
|
||||||
public abstract record Result<TValue, TError> {
|
public abstract record Result<TValue, TError> {
|
||||||
private Result() {}
|
private Result() {}
|
||||||
@ -42,7 +44,7 @@ public abstract record Result<TError> {
|
|||||||
return new Fail(error);
|
return new Fail(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator Result<TError>(Result.OkType _) {
|
public static implicit operator Result<TError>([SuppressMessage("ReSharper", "UnusedParameter.Global")] Result.OkType _) {
|
||||||
return new Ok();
|
return new Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
namespace Phantom.Utils.Threading;
|
|
||||||
|
|
||||||
public sealed class ThreadSafeLinkedList<T> : IDisposable {
|
|
||||||
private readonly LinkedList<T> list = new ();
|
|
||||||
private readonly SemaphoreSlim semaphore = new (1, 1);
|
|
||||||
|
|
||||||
public async Task Add(T item, bool toFront, CancellationToken cancellationToken) {
|
|
||||||
await semaphore.WaitAsync(cancellationToken);
|
|
||||||
try {
|
|
||||||
if (toFront) {
|
|
||||||
list.AddFirst(item);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
list.AddLast(item);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
semaphore.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<T?> TryTakeFromFront(CancellationToken cancellationToken) {
|
|
||||||
await semaphore.WaitAsync(cancellationToken);
|
|
||||||
try {
|
|
||||||
var firstNode = list.First;
|
|
||||||
if (firstNode == null) {
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
list.RemoveFirst();
|
|
||||||
return firstNode.Value;
|
|
||||||
} finally {
|
|
||||||
semaphore.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() {
|
|
||||||
semaphore.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
namespace Phantom.Utils.Threading;
|
|
||||||
|
|
||||||
public sealed class ThreadSafeStructRef<T> : IDisposable where T : struct {
|
|
||||||
private T? value;
|
|
||||||
private readonly SemaphoreSlim semaphore = new (1, 1);
|
|
||||||
|
|
||||||
public async Task<T?> Get(CancellationToken cancellationToken) {
|
|
||||||
await semaphore.WaitAsync(cancellationToken);
|
|
||||||
try {
|
|
||||||
return value;
|
|
||||||
} finally {
|
|
||||||
semaphore.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Set(T? value, CancellationToken cancellationToken) {
|
|
||||||
await semaphore.WaitAsync(cancellationToken);
|
|
||||||
try {
|
|
||||||
this.value = value;
|
|
||||||
} finally {
|
|
||||||
semaphore.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() {
|
|
||||||
semaphore.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user