Spike: net48-only launcher (evaluate size vs net8 self-contained)
Converts the Launcher Service + Agent from net8/win-x64 self-contained to net48 framework-dependent, and makes Tesla.Contract net48-only (drops multi-targeting). Both consumers (Console + Launcher) are now a single TFM. Code changes for net48 (the only net8/netstandard2.1 APIs in use): - RandomNumberGenerator.Fill -> RandomNumberGenerator.Create().GetBytes (3x) - TcpListener.AcceptTcpClientAsync(ct) -> AcceptTcpClientAsync() + stop-on-cancel - byte[].AsSpan().SequenceEqual -> Linq SequenceEqual (no System.Memory) (2x) - PipeStream.Write(byte[]) / WriteAsync(byte[],ct) -> explicit (buf,0,len[,ct]) - Math.Clamp -> Math.Max/Min The generic host (Microsoft.Extensions.Hosting 8.x + UseWindowsService) runs on net48 unchanged. build.bat/install.bat updated for the folder-of-DLLs deploy; solution platform reverted x64 -> AnyCPU. RESULT — package size: ~3.7 MB on disk / 1.58 MB zipped, vs ~213 MB / 91 MB for the net8 self-contained build (~50-58x smaller). net48 ships in Win10/11 so no runtime prerequisite. 73 tests green; NOT re-validated on a live pod. Spike branch for evaluation — do not merge without a pod re-test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.IO.Pipes;
|
||||
@@ -151,31 +152,39 @@ namespace Tesla.Launcher.Service
|
||||
_listener.Start();
|
||||
_logger.LogInformation("Listening. Waiting for Console connections...");
|
||||
|
||||
// net48's TcpListener has no CancellationToken overload for accept;
|
||||
// stop the listener on cancellation so the pending accept unblocks.
|
||||
using var stopReg = stoppingToken.Register(() => { try { _listener.Stop(); } catch { } });
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
TcpClient client;
|
||||
try
|
||||
{
|
||||
var client = await _listener.AcceptTcpClientAsync(stoppingToken);
|
||||
_logger.LogInformation(
|
||||
"Console connected from {EP}", client.Client.RemoteEndPoint);
|
||||
|
||||
// Handle each Console connection on its own thread.
|
||||
// Frame reads are synchronous, so we offload to a
|
||||
// thread-pool thread via Task.Run.
|
||||
var task = Task.Run(
|
||||
() => HandleConsoleClient(client, stoppingToken),
|
||||
stoppingToken);
|
||||
|
||||
lock (_taskLock)
|
||||
{
|
||||
_clientTasks.Add(task);
|
||||
_clientTasks.RemoveAll(t => t.IsCompleted);
|
||||
}
|
||||
client = await _listener.AcceptTcpClientAsync();
|
||||
}
|
||||
catch (OperationCanceledException) { break; }
|
||||
catch (Exception) when (stoppingToken.IsCancellationRequested) { break; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error accepting Console connection");
|
||||
continue;
|
||||
}
|
||||
|
||||
_logger.LogInformation(
|
||||
"Console connected from {EP}", client.Client.RemoteEndPoint);
|
||||
|
||||
// Handle each Console connection on its own thread.
|
||||
// Frame reads are synchronous, so we offload to a
|
||||
// thread-pool thread via Task.Run.
|
||||
var task = Task.Run(
|
||||
() => HandleConsoleClient(client, stoppingToken),
|
||||
stoppingToken);
|
||||
|
||||
lock (_taskLock)
|
||||
{
|
||||
_clientTasks.Add(task);
|
||||
_clientTasks.RemoveAll(t => t.IsCompleted);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,7 +218,7 @@ namespace Tesla.Launcher.Service
|
||||
|
||||
// Generate and send our IV
|
||||
var podIv = new byte[16];
|
||||
RandomNumberGenerator.Fill(podIv);
|
||||
using (var rng = RandomNumberGenerator.Create()) rng.GetBytes(podIv);
|
||||
netStream.Write(podIv, 0, 16);
|
||||
netStream.Flush();
|
||||
|
||||
@@ -230,7 +239,7 @@ namespace Tesla.Launcher.Service
|
||||
_logger.LogWarning("CONF read failed: {Msg}", ex.Message);
|
||||
return;
|
||||
}
|
||||
if (!confReply.AsSpan().SequenceEqual(confMsg))
|
||||
if (!confReply.SequenceEqual(confMsg))
|
||||
{
|
||||
_logger.LogWarning("CONF mismatch — session key mismatch, dropping connection.");
|
||||
return;
|
||||
@@ -879,8 +888,8 @@ namespace Tesla.Launcher.Service
|
||||
|
||||
// Send IpcMessage
|
||||
var reqBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(msg));
|
||||
await pipe.WriteAsync(BitConverter.GetBytes(reqBytes.Length), ct);
|
||||
await pipe.WriteAsync(reqBytes, ct);
|
||||
await pipe.WriteAsync(BitConverter.GetBytes(reqBytes.Length), 0, 4, ct);
|
||||
await pipe.WriteAsync(reqBytes, 0, reqBytes.Length, ct);
|
||||
await pipe.FlushAsync(ct);
|
||||
|
||||
// Read IpcResponse
|
||||
|
||||
Reference in New Issue
Block a user