1
0
mirror of https://github.com/chylex/Minecraft-Phantom-Panel.git synced 2024-11-24 22:42:53 +01:00
Minecraft-Phantom-Panel/Utils/Phantom.Utils.Rpc/RpcRuntime.cs

74 lines
2.1 KiB
C#

using NetMQ;
using Phantom.Utils.Rpc.Message;
using Phantom.Utils.Runtime;
using Serilog;
namespace Phantom.Utils.Rpc;
static class RpcRuntime {
private static bool HasRuntime { get; set; }
internal static void MarkRuntimeCreated() {
if (HasRuntime) {
throw new InvalidOperationException("Only one instance of RpcRuntime can be created.");
}
HasRuntime = true;
}
internal static void SetDefaultSocketOptions(ThreadSafeSocketOptions options) {
// TODO test behavior when either agent or server are offline for a very long time
options.DelayAttachOnConnect = true;
options.ReceiveHighWatermark = 10_000;
options.SendHighWatermark = 10_000;
}
}
public abstract class RpcRuntime<TSocket> where TSocket : ThreadSafeSocket, new() {
private readonly TSocket socket;
private readonly ILogger runtimeLogger;
private readonly MessageReplyTracker replyTracker;
private readonly TaskManager taskManager;
protected RpcRuntime(RpcConfiguration configuration, TSocket socket) {
RpcRuntime.MarkRuntimeCreated();
RpcRuntime.SetDefaultSocketOptions(socket.Options);
this.socket = socket;
this.runtimeLogger = configuration.RuntimeLogger;
this.replyTracker = new MessageReplyTracker(runtimeLogger);
this.taskManager = new TaskManager(configuration.TaskManagerLogger);
}
protected async Task Launch() {
Connect(socket);
void RunTask() {
try {
Run(socket, replyTracker, taskManager);
} catch (Exception e) {
runtimeLogger.Error(e, "Caught exception in RPC thread.");
}
}
try {
await Task.Factory.StartNew(RunTask, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
} catch (OperationCanceledException) {
// ignore
} finally {
await taskManager.Stop();
await Disconnect();
socket.Dispose();
NetMQConfig.Cleanup();
runtimeLogger.Information("ZeroMQ client stopped.");
}
}
protected abstract void Connect(TSocket socket);
protected abstract void Run(TSocket socket, MessageReplyTracker replyTracker, TaskManager taskManager);
protected virtual Task Disconnect() {
return Task.CompletedTask;
}
}