Migrated the entire boot sequence to use the runtime API server

This commit is contained in:
tsommer committed 2024-08-25 11:23:41 +02:00
1 parent fc3ab64787
commit 0c9df7d05c
4 files changed
+232 -68

No files matched your search

+13 -5
View File
@@ -11,7 +11,15 @@ using System.Reflection;
using Microsoft.Extensions.FileProviders;
#endif
var port = args.Length > 0 ? args[0] : "5000";
var rustApiPort = args.Length > 0 ? args[0] : "5000";
using var rust = new Rust(rustApiPort);
var appPort = await rust.GetAppPort();
if(appPort == 0)
{
Console.WriteLine("Failed to get the app port from Rust.");
return;
}
var builder = WebApplication.CreateBuilder();
builder.Services.AddMudServices(config =>
{
@@ -27,7 +35,7 @@ builder.Services.AddMudServices(config =>
builder.Services.AddMudMarkdownServices();
builder.Services.AddSingleton(MessageBus.INSTANCE);
builder.Services.AddSingleton<Rust>();
builder.Services.AddSingleton(rust);
builder.Services.AddMudMarkdownClipboardService<MarkdownClipboardService>();
builder.Services.AddSingleton<SettingsManager>();
builder.Services.AddSingleton<ThreadSafeRandom>();
@@ -46,10 +54,10 @@ builder.Services.AddRazorComponents()
builder.Services.AddSingleton(new HttpClient
{
BaseAddress = new Uri($"http://localhost:{port}")
BaseAddress = new Uri($"http://localhost:{appPort}")
});
builder.WebHost.UseUrls($"http://localhost:{port}");
builder.WebHost.UseUrls($"http://localhost:{appPort}");
#if DEBUG
builder.WebHost.UseWebRoot("wwwroot");
@@ -79,5 +87,5 @@ app.MapRazorComponents<App>()
var serverTask = app.RunAsync();
Console.WriteLine("RUST/TAURI SERVER STARTED");
await rust.AppIsReady();
await serverTask;
+67 -1
View File
@@ -3,8 +3,65 @@ namespace AIStudio.Tools;
/// <summary>
/// Calling Rust functions.
/// </summary>
public sealed class Rust
public sealed class Rust(string apiPort) : IDisposable
{
private readonly HttpClient http = new()
{
BaseAddress = new Uri($"http://127.0.0.1:{apiPort}"),
};
public async Task<int> GetAppPort()
{
Console.WriteLine("Trying to get app port from Rust runtime...");
//
// Note I: In the production environment, the Rust runtime is already running
// and listening on the given port. In the development environment, the IDE
// starts the Rust runtime in parallel with the .NET runtime. Since the
// Rust runtime needs some time to start, we have to wait for it to be ready.
//
const int MAX_TRIES = 160;
var tris = 0;
var wait4Try = TimeSpan.FromMilliseconds(250);
var url = new Uri($"http://127.0.0.1:{apiPort}/system/dotnet/port");
while (tris++ < MAX_TRIES)
{
//
// Note II: We use a new HttpClient instance for each try to avoid
// .NET is caching the result. When we use the same HttpClient
// instance, we would always get the same result (403 forbidden),
// without even trying to connect to the Rust server.
//
using var initialHttp = new HttpClient();
var response = await initialHttp.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($" Try {tris}/{MAX_TRIES}");
await Task.Delay(wait4Try);
continue;
}
var appPortContent = await response.Content.ReadAsStringAsync();
var appPort = int.Parse(appPortContent);
Console.WriteLine($" Received app port from Rust runtime: '{appPort}'");
return appPort;
}
Console.WriteLine("Failed to receive the app port from Rust runtime.");
return 0;
}
public async Task AppIsReady()
{
const string URL = "/system/dotnet/ready";
Console.WriteLine($"Notifying Rust runtime that the app is ready.");
var response = await this.http.PostAsync(URL, new StringContent(string.Empty));
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"Failed to notify Rust runtime that the app is ready: '{response.StatusCode}'");
}
}
/// <summary>
/// Tries to copy the given text to the clipboard.
/// </summary>
@@ -51,4 +108,13 @@ public sealed class Rust
var cts = new CancellationTokenSource();
await jsRuntime.InvokeVoidAsync("window.__TAURI__.invoke", cts.Token, "install_update");
}
#region IDisposable
public void Dispose()
{
this.http.Dispose();
}
#endregion
}