mirror of
				https://github.com/chylex/Minecraft-Phantom-Panel.git
				synced 2025-11-04 03:40:15 +01:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			96456f90bc
			...
			experiment
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						fad7b35e04
	
				 | 
					
					
						
@@ -1,7 +1,6 @@
 | 
				
			|||||||
using NetMQ.Sockets;
 | 
					using NetMQ.Sockets;
 | 
				
			||||||
using Phantom.Agent.Rpc;
 | 
					using Phantom.Agent.Rpc;
 | 
				
			||||||
using Phantom.Common.Data.Replies;
 | 
					using Phantom.Common.Data.Replies;
 | 
				
			||||||
using Phantom.Common.Logging;
 | 
					 | 
				
			||||||
using Phantom.Common.Messages;
 | 
					using Phantom.Common.Messages;
 | 
				
			||||||
using Phantom.Common.Messages.ToAgent;
 | 
					using Phantom.Common.Messages.ToAgent;
 | 
				
			||||||
using Phantom.Common.Messages.ToServer;
 | 
					using Phantom.Common.Messages.ToServer;
 | 
				
			||||||
@@ -50,6 +49,11 @@ public sealed class MessageListener : IMessageToAgentListener {
 | 
				
			|||||||
		return Task.CompletedTask;
 | 
							return Task.CompletedTask;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						public Task HandleShutdownAgent(ShutdownAgentMessage message) {
 | 
				
			||||||
 | 
							shutdownTokenSource.Cancel();
 | 
				
			||||||
 | 
							return Task.CompletedTask;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public async Task HandleConfigureInstance(ConfigureInstanceMessage message) {
 | 
						public async Task HandleConfigureInstance(ConfigureInstanceMessage message) {
 | 
				
			||||||
		await socket.SendSimpleReply(message, await agent.InstanceSessionManager.Configure(message.Configuration));
 | 
							await socket.SendSimpleReply(message, await agent.InstanceSessionManager.Configure(message.Configuration));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,4 +9,5 @@ public interface IMessageToAgentListener {
 | 
				
			|||||||
	Task HandleLaunchInstance(LaunchInstanceMessage message);
 | 
						Task HandleLaunchInstance(LaunchInstanceMessage message);
 | 
				
			||||||
	Task HandleStopInstance(StopInstanceMessage message);
 | 
						Task HandleStopInstance(StopInstanceMessage message);
 | 
				
			||||||
	Task HandleSendCommandToInstance(SendCommandToInstanceMessage message);
 | 
						Task HandleSendCommandToInstance(SendCommandToInstanceMessage message);
 | 
				
			||||||
 | 
						Task HandleShutdownAgent(ShutdownAgentMessage message);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ public static class MessageRegistries {
 | 
				
			|||||||
		ToAgent.Add<LaunchInstanceMessage>(3);
 | 
							ToAgent.Add<LaunchInstanceMessage>(3);
 | 
				
			||||||
		ToAgent.Add<StopInstanceMessage>(4);
 | 
							ToAgent.Add<StopInstanceMessage>(4);
 | 
				
			||||||
		ToAgent.Add<SendCommandToInstanceMessage>(5);
 | 
							ToAgent.Add<SendCommandToInstanceMessage>(5);
 | 
				
			||||||
 | 
							ToAgent.Add<ShutdownAgentMessage>(6);
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		ToServer.Add<RegisterAgentMessage>(0);
 | 
							ToServer.Add<RegisterAgentMessage>(0);
 | 
				
			||||||
		ToServer.Add<UnregisterAgentMessage>(1);
 | 
							ToServer.Add<UnregisterAgentMessage>(1);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					using MessagePack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Phantom.Common.Messages.ToAgent; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[MessagePackObject]
 | 
				
			||||||
 | 
					public sealed record ShutdownAgentMessage : IMessageToAgent {
 | 
				
			||||||
 | 
						public Task Accept(IMessageToAgentListener listener) {
 | 
				
			||||||
 | 
							return listener.HandleShutdownAgent(this);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -92,7 +92,7 @@ public sealed class AgentManager {
 | 
				
			|||||||
		agents.Update(agentGuid, static agent => agent with { LastPing = DateTimeOffset.Now });
 | 
							agents.Update(agentGuid, static agent => agent with { LastPing = DateTimeOffset.Now });
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private async Task<bool> SendMessage<TMessage>(Guid guid, TMessage message) where TMessage : IMessageToAgent {
 | 
						public async Task<bool> SendMessage<TMessage>(Guid guid, TMessage message) where TMessage : IMessageToAgent {
 | 
				
			||||||
		var connection = agents.GetConnection(guid);
 | 
							var connection = agents.GetConnection(guid);
 | 
				
			||||||
		if (connection != null) {
 | 
							if (connection != null) {
 | 
				
			||||||
			await connection.SendMessage(message);
 | 
								await connection.SendMessage(message);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
@page "/agents"
 | 
					@page "/agents"
 | 
				
			||||||
@using System.Collections.Immutable
 | 
					@using System.Collections.Immutable
 | 
				
			||||||
@using Phantom.Common.Data.Agent
 | 
					@using Phantom.Common.Data.Agent
 | 
				
			||||||
 | 
					@using Phantom.Common.Messages.ToAgent
 | 
				
			||||||
@using Phantom.Server.Services.Agents
 | 
					@using Phantom.Server.Services.Agents
 | 
				
			||||||
@using Phantom.Utils.Collections
 | 
					@using Phantom.Utils.Collections
 | 
				
			||||||
@implements IDisposable
 | 
					@implements IDisposable
 | 
				
			||||||
@@ -20,11 +21,13 @@
 | 
				
			|||||||
      <th style="width: 350px;">Identifier</th>
 | 
					      <th style="width: 350px;">Identifier</th>
 | 
				
			||||||
      <th style="width: 150px;" class="text-center">Status</th>
 | 
					      <th style="width: 150px;" class="text-center">Status</th>
 | 
				
			||||||
      <th style="width: 250px;" class="text-right">Last Ping</th>
 | 
					      <th style="width: 250px;" class="text-right">Last Ping</th>
 | 
				
			||||||
 | 
					      <th style="width: 200px;">Actions</th>
 | 
				
			||||||
    </tr>
 | 
					    </tr>
 | 
				
			||||||
  </thead>
 | 
					  </thead>
 | 
				
			||||||
  @if (!agentTable.IsEmpty) {
 | 
					  @if (!agentTable.IsEmpty) {
 | 
				
			||||||
    <tbody>
 | 
					    <tbody>
 | 
				
			||||||
      @foreach (var agent in agentTable) {
 | 
					      @foreach (var row in agentTable) {
 | 
				
			||||||
 | 
					        var agent = row.Agent;
 | 
				
			||||||
        var stats = agentStats.TryGetValue(agent.Guid, out var s) ? s : null;
 | 
					        var stats = agentStats.TryGetValue(agent.Guid, out var s) ? s : null;
 | 
				
			||||||
        var usedInstances = stats?.UsedInstances;
 | 
					        var usedInstances = stats?.UsedInstances;
 | 
				
			||||||
        var usedMemory = stats?.UsedMemory.InMegabytes;
 | 
					        var usedMemory = stats?.UsedMemory.InMegabytes;
 | 
				
			||||||
@@ -48,6 +51,9 @@
 | 
				
			|||||||
          @if (agent.IsOnline) {
 | 
					          @if (agent.IsOnline) {
 | 
				
			||||||
            <td class="text-center text-success">Online</td>
 | 
					            <td class="text-center text-success">Online</td>
 | 
				
			||||||
            <td class="text-right"></td>
 | 
					            <td class="text-right"></td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					              <button type="button" class="btn btn-danger btn-sm" @onclick="() => ShutdownAgent(agent.Guid)" disabled="@row.IsShutdownButtonDisabled">Shutdown</button>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          else {
 | 
					          else {
 | 
				
			||||||
            <td class="text-center text-danger">Offline</td>
 | 
					            <td class="text-center text-danger">Offline</td>
 | 
				
			||||||
@@ -59,6 +65,7 @@
 | 
				
			|||||||
            else {
 | 
					            else {
 | 
				
			||||||
              <td class="text-right">-</td>
 | 
					              <td class="text-right">-</td>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            <td>-</td>
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        </tr>
 | 
					        </tr>
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -66,7 +73,7 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  <tfoot>
 | 
					  <tfoot>
 | 
				
			||||||
    <tr>
 | 
					    <tr>
 | 
				
			||||||
      <td colspan="7">
 | 
					      <td colspan="8">
 | 
				
			||||||
        @if (agentTable.IsEmpty) {
 | 
					        @if (agentTable.IsEmpty) {
 | 
				
			||||||
          <text>No agents registered.</text>
 | 
					          <text>No agents registered.</text>
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -78,13 +85,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@code {
 | 
					@code {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private readonly Table<Agent, Guid> agentTable = new();
 | 
					  private readonly Table<AgentRow, Guid> agentTable = new();
 | 
				
			||||||
  private ImmutableDictionary<Guid, AgentStats> agentStats = ImmutableDictionary<Guid, AgentStats>.Empty;
 | 
					  private ImmutableDictionary<Guid, AgentStats> agentStats = ImmutableDictionary<Guid, AgentStats>.Empty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private readonly record struct AgentRow(Agent Agent, bool IsShutdownButtonDisabled = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected override void OnInitialized() {
 | 
					  protected override void OnInitialized() {
 | 
				
			||||||
    AgentManager.AgentsChanged.Subscribe(this, agents => {
 | 
					    AgentManager.AgentsChanged.Subscribe(this, agents => {
 | 
				
			||||||
      var sortedAgents = agents.Sort(static (a1, a2) => a1.Name.CompareTo(a2.Name));
 | 
					      var sortedAgents = agents.Sort(static (a1, a2) => a1.Name.CompareTo(a2.Name));
 | 
				
			||||||
      agentTable.UpdateFrom(sortedAgents, static agent => agent.Guid, static agent => agent, static (agent, _) => agent);
 | 
					      agentTable.UpdateFrom(sortedAgents, static agent => agent.Guid, static agent => new AgentRow(agent), static (agent, row) => row with { Agent = agent });
 | 
				
			||||||
      InvokeAsync(StateHasChanged);
 | 
					      InvokeAsync(StateHasChanged);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -94,6 +103,12 @@
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async Task ShutdownAgent(Guid guid) {
 | 
				
			||||||
 | 
					    if (agentTable.TryUpdateRow(guid, static row => row with { IsShutdownButtonDisabled = true })) {
 | 
				
			||||||
 | 
					      await AgentManager.SendMessage(guid, new ShutdownAgentMessage());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void IDisposable.Dispose() {
 | 
					  void IDisposable.Dispose() {
 | 
				
			||||||
    AgentManager.AgentsChanged.Unsubscribe(this);
 | 
					    AgentManager.AgentsChanged.Unsubscribe(this);
 | 
				
			||||||
    AgentStatsManager.AgentStatsChanged.Unsubscribe(this);
 | 
					    AgentStatsManager.AgentStatsChanged.Unsubscribe(this);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user