mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2025-04-28 19:15:45 +02:00
61 lines
1.4 KiB
C#
61 lines
1.4 KiB
C#
using System.Threading.Channels;
|
|
using Phantom.Utils.Tasks;
|
|
|
|
namespace Phantom.Utils.Rpc;
|
|
|
|
sealed class RpcQueue {
|
|
private readonly Channel<Func<Task>> channel = Channel.CreateUnbounded<Func<Task>>(new UnboundedChannelOptions {
|
|
SingleReader = true,
|
|
SingleWriter = false,
|
|
AllowSynchronousContinuations = false
|
|
});
|
|
|
|
private readonly Task processingTask;
|
|
|
|
public RpcQueue(TaskManager taskManager, string taskName) {
|
|
this.processingTask = taskManager.Run(taskName, Process);
|
|
}
|
|
|
|
public Task Enqueue(Action action) {
|
|
return Enqueue(() => {
|
|
action();
|
|
return Task.CompletedTask;
|
|
});
|
|
}
|
|
|
|
public Task Enqueue(Func<Task> task) {
|
|
var completionSource = AsyncTasks.CreateCompletionSource();
|
|
|
|
if (!channel.Writer.TryWrite(() => task().ContinueWith(t => completionSource.SetResultFrom(t)))) {
|
|
completionSource.SetCanceled();
|
|
}
|
|
|
|
return completionSource.Task;
|
|
}
|
|
|
|
public Task<T> Enqueue<T>(Func<Task<T>> task) {
|
|
var completionSource = AsyncTasks.CreateCompletionSource<T>();
|
|
|
|
if (!channel.Writer.TryWrite(() => task().ContinueWith(t => completionSource.SetResultFrom(t)))) {
|
|
completionSource.SetCanceled();
|
|
}
|
|
|
|
return completionSource.Task;
|
|
}
|
|
|
|
private async Task Process() {
|
|
try {
|
|
await foreach (var task in channel.Reader.ReadAllAsync()) {
|
|
await task();
|
|
}
|
|
} catch (OperationCanceledException) {
|
|
// Ignore.
|
|
}
|
|
}
|
|
|
|
public Task Stop() {
|
|
channel.Writer.Complete();
|
|
return processingTask;
|
|
}
|
|
}
|