WuhuIslandTesting/Library/PackageCache/com.unity.scriptablebuildpipeline@1.21.5/Tests/Editor/LocalCacheServer.cs

147 lines
4.5 KiB
C#
Raw Normal View History

2025-01-07 02:06:59 +01:00
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using UnityEditor;
using UnityEngine;
namespace UnityEditor.Build.Pipeline.Tests
{
class LocalCacheServer : ScriptableSingleton<LocalCacheServer>
{
[SerializeField] public string m_path;
[SerializeField] public int m_port;
[SerializeField] public int m_pid = -1;
public static string Combine(params string[] components)
{
if (components.Length < 1)
throw new ArgumentException("At least one component must be provided!");
var path1 = components[0];
for (var index = 1; index < components.Length; ++index)
path1 = Path.Combine(path1, components[index]);
return path1;
}
private void Create(int port, ulong size, string cachePath)
{
var nodeExecutable = Combine(EditorApplication.applicationContentsPath, "Tools", "nodejs");
nodeExecutable = Application.platform == RuntimePlatform.WindowsEditor
? Combine(nodeExecutable, "node.exe")
: Combine(nodeExecutable, "bin", "node");
if (!Directory.Exists(cachePath))
Directory.CreateDirectory(cachePath);
m_path = cachePath;
var cacheServerJs = Combine(EditorApplication.applicationContentsPath, "Tools", "CacheServer", "main.js");
var processStartInfo = new ProcessStartInfo(nodeExecutable)
{
Arguments = "\"" + cacheServerJs + "\""
+ " --port " + port
+ " --path \"" + m_path
+ "\" --nolegacy"
+ " --monitor-parent-process " + Process.GetCurrentProcess().Id
// node.js has issues running on windows with stdout not redirected.
// so we silence logging to avoid that. And also to avoid CacheServer
// spamming the editor logs on OS X.
+ " --silent"
+ " --size " + size,
UseShellExecute = false,
CreateNoWindow = true
};
var p = new Process { StartInfo = processStartInfo };
p.Start();
m_port = port;
m_pid = p.Id;
Save(true);
}
public static string CachePath
{
get { return instance.m_path; }
}
public static int Port
{
get { return instance.m_port; }
}
public static void Setup(ulong size, string cachePath)
{
Kill();
instance.Create(GetRandomUnusedPort(), size, cachePath);
WaitForServerToComeAlive(instance.m_port);
}
public static void Kill()
{
if (instance.m_pid == -1)
return;
try
{
var p = Process.GetProcessById(instance.m_pid);
p.Kill();
instance.m_pid = -1;
}
catch
{
// if we could not get a process, there is non alive. continue.
}
}
public static void Clear()
{
Kill();
if (Directory.Exists(instance.m_path))
Directory.Delete(instance.m_path, true);
}
private static void WaitForServerToComeAlive(int port)
{
var start = DateTime.Now;
var maximum = start.AddSeconds(5);
while (DateTime.Now < maximum)
{
if (!PingHost("localhost", port, 10)) continue;
Console.WriteLine("Server Came alive after {0} ms", (DateTime.Now - start).TotalMilliseconds);
break;
}
}
private static int GetRandomUnusedPort()
{
var listener = new TcpListener(IPAddress.Any, 0);
listener.Start();
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
}
private static bool PingHost(string host, int port, int timeout)
{
try
{
using (var client = new TcpClient())
{
var result = client.BeginConnect(host, port, null, null);
result.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(timeout));
return client.Connected;
}
}
catch
{
return false;
}
}
}
}