Improved enterprise IT (#497)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2025-06-09 14:06:54 +02:00
1 parent 7a498d524e
commit 32e1ab977d
9 files changed
+200 -21

No files matched your search

@@ -1129,7 +1129,7 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3032662264"] = "Benutzerdefinierte Sprache"
-- Your input to improve
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3037449423"] = "Ihr Vorschlag zur Verbesserung"
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3037449423"] = "Ihr Text, der verbessert werden soll"
-- Writing style
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3754048862"] = "Schreibstil"
@@ -4213,7 +4213,7 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2173617769"] = "Diese Bibliothek wird
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2174764529"] = "Für die sichere Kommunikation zwischen der Benutzeroberfläche und der Laufzeit müssen wir Zertifikate erstellen. Diese Rust-Bibliothek eignet sich hervorragend dafür."
-- AI Studio runs without an enterprise configuration.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "AI Studio läuft ohne eine Konfiguration ihrer Organisation."
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "Dies ist eine private AI Studio-Installation. Es wird keine Konfiguration einer Organisation verwendet."
-- OK
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2246359087"] = "OK"
@@ -4213,7 +4213,7 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2173617769"] = "This library is used t
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2174764529"] = "For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose."
-- AI Studio runs without an enterprise configuration.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "AI Studio runs without an enterprise configuration."
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "This is a private AI Studio installation. It runs without an enterprise configuration."
-- OK
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2246359087"] = "OK"
@@ -42,6 +42,7 @@ public static partial class PluginFactory
var tempDownloadFile = Path.GetTempFileName();
try
{
await LockHotReloadAsync();
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync(downloadUrl, cancellationToken);
if (response.IsSuccessStatusCode)
@@ -80,6 +81,8 @@ public static partial class PluginFactory
LOG.LogError(e, "Failed to delete the temporary download file.");
}
}
UnlockHotReload();
}
return true;
@@ -46,12 +46,41 @@ public static partial class PluginFactory
try
{
LOG.LogInformation($"File changed ({changeType}): {args.FullPath}. Reloading plugins...");
// Wait for parallel writes to finish:
await Task.Delay(TimeSpan.FromSeconds(3));
if (File.Exists(HOT_RELOAD_LOCK_FILE))
{
LOG.LogInformation("Hot reload lock file exists. Waiting for it to be released before proceeding with the reload.");
var lockFileCancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var token = lockFileCancellationTokenSource.Token;
var waitTime = TimeSpan.FromSeconds(1);
while (File.Exists(HOT_RELOAD_LOCK_FILE) && !token.IsCancellationRequested)
{
try
{
LOG.LogDebug("Waiting for hot reload lock to be released...");
await Task.Delay(waitTime, token);
waitTime = TimeSpan.FromSeconds(Math.Min(waitTime.TotalSeconds * 2, 120)); // Exponential backoff with a cap
}
catch (TaskCanceledException)
{
// Case: The cancellation token was triggered, meaning the lock file is still present.
// We expect that something goes wrong. So, we try to delete the lock file:
LOG.LogWarning("Hot reload lock file still exists after 30 seconds. Attempting to delete it...");
UnlockHotReload();
break;
}
}
LOG.LogInformation("Hot reload lock file released. Proceeding with plugin reload.");
}
await LoadAll();
await MessageBus.INSTANCE.SendMessage<bool>(null, Event.PLUGINS_RELOADED);
}
catch(Exception e)
{
LOG.LogError(e, $"Error while reloading plugins after change in file '{args.FullPath}' with change type '{changeType}'.");
}
finally
{
HOT_RELOAD_SEMAPHORE.Release();
@@ -13,6 +13,7 @@ public static partial class PluginFactory
private static string PLUGINS_ROOT = string.Empty;
private static string INTERNAL_PLUGINS_ROOT = string.Empty;
private static string CONFIGURATION_PLUGINS_ROOT = string.Empty;
private static string HOT_RELOAD_LOCK_FILE = string.Empty;
private static FileSystemWatcher HOT_RELOAD_WATCHER = null!;
private static ILanguagePlugin BASE_LANGUAGE_PLUGIN = NoPluginLanguage.INSTANCE;
@@ -30,6 +31,7 @@ public static partial class PluginFactory
LOG.LogInformation("Initializing plugin factory...");
DATA_DIR = SettingsManager.DataDirectory!;
PLUGINS_ROOT = Path.Join(DATA_DIR, "plugins");
HOT_RELOAD_LOCK_FILE = Path.Join(PLUGINS_ROOT, ".lock");
INTERNAL_PLUGINS_ROOT = Path.Join(PLUGINS_ROOT, ".internal");
CONFIGURATION_PLUGINS_ROOT = Path.Join(PLUGINS_ROOT, ".config");
@@ -41,6 +43,51 @@ public static partial class PluginFactory
LOG.LogInformation("Plugin factory initialized successfully.");
return true;
}
private static async Task LockHotReloadAsync()
{
if (!IS_INITIALIZED)
{
LOG.LogError("PluginFactory is not initialized.");
return;
}
try
{
if (File.Exists(HOT_RELOAD_LOCK_FILE))
{
LOG.LogWarning("Hot reload lock file already exists.");
return;
}
await File.WriteAllTextAsync(HOT_RELOAD_LOCK_FILE, DateTime.UtcNow.ToString("o"));
}
catch (Exception e)
{
LOG.LogError(e, "An error occurred while trying to lock hot reloading.");
}
}
private static void UnlockHotReload()
{
if (!IS_INITIALIZED)
{
LOG.LogError("PluginFactory is not initialized.");
return;
}
try
{
if(File.Exists(HOT_RELOAD_LOCK_FILE))
File.Delete(HOT_RELOAD_LOCK_FILE);
else
LOG.LogWarning("Hot reload lock file does not exist. Nothing to unlock.");
}
catch (Exception e)
{
LOG.LogError(e, "An error occurred while trying to unlock hot reloading.");
}
}
public static void Dispose()
{
@@ -1 +1,3 @@
# v0.9.48, build 223 (2025-06-xx xx:xx UTC)
- Improved German translation.
- Improved how configurations are applied in organizations and made the process more robust.