diff --git a/src/Server/AIProvider.cs b/src/Server/AIProvider.cs index 0f83731..5194a4d 100644 --- a/src/Server/AIProvider.cs +++ b/src/Server/AIProvider.cs @@ -109,10 +109,19 @@ public class AIProvider { JObject responseContentJson = JObject.Parse(responseContent); List? responseContentTokens = [.. responseContentJson.SelectTokens(embeddingsJsonPath)]; - if (responseContentTokens is null) + if (responseContentTokens is null || responseContentTokens.Count == 0) { - _logger.LogError("Unable to select tokens using JSONPath {embeddingsJsonPath} for string: {responseContent}.", [embeddingsJsonPath, responseContent]); - throw new JSONPathSelectionException(embeddingsJsonPath, responseContent); + if (responseContentJson.TryGetValue("error", out JToken? errorMessageJson) && errorMessageJson is not null) + { + string errorMessage = errorMessageJson.Value() ?? ""; + _logger.LogError("Unable to retrieve embeddings due to error: {errorMessage}", [errorMessage]); + throw new Exception($"Unable to retrieve embeddings due to error: {errorMessage}"); + + } else + { + _logger.LogError("Unable to select tokens using JSONPath {embeddingsJsonPath} for string: {responseContent}.", [embeddingsJsonPath, responseContent]); + throw new JSONPathSelectionException(embeddingsJsonPath, responseContent); + } } return [.. responseContentTokens.Select(token => token.ToObject() ?? throw new Exception("Unable to cast embeddings response to float[]"))]; } diff --git a/src/Server/Controllers/SearchdomainController.cs b/src/Server/Controllers/SearchdomainController.cs index 57228e1..eecef76 100644 --- a/src/Server/Controllers/SearchdomainController.cs +++ b/src/Server/Controllers/SearchdomainController.cs @@ -109,7 +109,7 @@ public class SearchdomainController : ControllerBase /// Updated name of the searchdomain /// Updated settings of searchdomain [HttpPut] - public ActionResult Update([Required]string searchdomain, string newName, [FromBody]SearchdomainSettings? settings) + public async Task> Update([Required]string searchdomain, string newName, [FromBody]SearchdomainSettings? settings) { (Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger); if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message}); @@ -120,7 +120,7 @@ public class SearchdomainController : ControllerBase {"name", newName}, {"id", searchdomain_.id} }; - searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set name = @name WHERE id = @id", parameters); + await searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set name = @name WHERE id = @id", parameters); } else { Dictionary parameters = new() @@ -129,7 +129,7 @@ public class SearchdomainController : ControllerBase {"settings", settings}, {"id", searchdomain_.id} }; - searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set name = @name, settings = @settings WHERE id = @id", parameters); + await searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set name = @name, settings = @settings WHERE id = @id", parameters); } return Ok(new SearchdomainUpdateResults(){Success = true}); } @@ -230,8 +230,9 @@ public class SearchdomainController : ControllerBase /// Update the settings of a searchdomain /// /// Name of the searchdomain + /// Settings to apply to the searchdomain [HttpPut("Settings")] - public ActionResult UpdateSettings([Required]string searchdomain, [Required][FromBody] SearchdomainSettings request) + public async Task> UpdateSettings([Required]string searchdomain, [Required][FromBody] SearchdomainSettings request) { (Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger); if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message}); @@ -240,7 +241,7 @@ public class SearchdomainController : ControllerBase {"settings", JsonSerializer.Serialize(request)}, {"id", searchdomain_.id} }; - searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set settings = @settings WHERE id = @id", parameters); + await searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set settings = @settings WHERE id = @id", parameters); searchdomain_.settings = request; searchdomain_.queryCache.Capacity = request.QueryCacheSize; return Ok(new SearchdomainUpdateResults(){Success = true}); diff --git a/src/Server/Controllers/ServerController.cs b/src/Server/Controllers/ServerController.cs index 35a0e01..1fb0594 100644 --- a/src/Server/Controllers/ServerController.cs +++ b/src/Server/Controllers/ServerController.cs @@ -68,7 +68,7 @@ public class ServerController : ControllerBase elementCount++; embeddingsCount += entry.Keys.Count; } - var sqlHelper = DatabaseHelper.GetSQLHelper(_options.Value); + var sqlHelper = _searchdomainManager.helper; var databaseTotalSize = DatabaseHelper.GetTotalDatabaseSize(sqlHelper); Task entityCountTask = DatabaseHelper.CountEntities(sqlHelper); long queryCacheUtilization = 0; diff --git a/src/Server/HealthChecks/ServerHealthChecks.cs b/src/Server/HealthChecks/ServerHealthChecks.cs index 4fc021b..fef432b 100644 --- a/src/Server/HealthChecks/ServerHealthChecks.cs +++ b/src/Server/HealthChecks/ServerHealthChecks.cs @@ -12,7 +12,7 @@ public class DatabaseHealthCheck : IHealthCheck _searchdomainManager = searchdomainManager; _logger = logger; } - public Task CheckHealthAsync( + public async Task CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { try @@ -22,23 +22,23 @@ public class DatabaseHealthCheck : IHealthCheck catch (Exception ex) { _logger.LogCritical("DatabaseHealthCheck - Exception occurred when retrieving and parsing database version: {ex}", ex.Message); - return Task.FromResult( + return await Task.FromResult( HealthCheckResult.Unhealthy()); } try { - _searchdomainManager.helper.ExecuteSQLNonQuery("INSERT INTO settings (name, value) VALUES ('test', 'x');", []); - _searchdomainManager.helper.ExecuteSQLNonQuery("DELETE FROM settings WHERE name = 'test';", []); + await _searchdomainManager.helper.ExecuteSQLNonQuery("INSERT INTO settings (name, value) VALUES ('test', 'x');", []); + await _searchdomainManager.helper.ExecuteSQLNonQuery("DELETE FROM settings WHERE name = 'test';", []); } catch (Exception ex) { _logger.LogCritical("DatabaseHealthCheck - Exception occurred when executing INSERT/DELETE query: {ex}", ex.Message); - return Task.FromResult( + return await Task.FromResult( HealthCheckResult.Unhealthy()); } - return Task.FromResult( + return await Task.FromResult( HealthCheckResult.Healthy()); } } diff --git a/src/Server/Helper/CacheHelper.cs b/src/Server/Helper/CacheHelper.cs index a80b6db..06a8dd1 100644 --- a/src/Server/Helper/CacheHelper.cs +++ b/src/Server/Helper/CacheHelper.cs @@ -72,7 +72,7 @@ public static class CacheHelper deletedEntries.Add(storeEntryIndex); } } - Task removeEntriesFromStoreTask = RemoveEntriesFromStore(helper, deletedEntries); + await RemoveEntriesFromStore(helper, deletedEntries); List<(int Index, KeyValuePair> Entry)> createdEntries = []; @@ -127,7 +127,6 @@ public static class CacheHelper var taskSet = new List { - removeEntriesFromStoreTask, CreateEntriesInStore(helper, createdEntries), UpdateEntryIndicesInStore(helper, changedEntries), AddModelsToIndices(helper, AddedModels), diff --git a/src/Server/Searchdomain.cs b/src/Server/Searchdomain.cs index 44beaee..5c0a0fe 100644 --- a/src/Server/Searchdomain.cs +++ b/src/Server/Searchdomain.cs @@ -23,11 +23,10 @@ public class Searchdomain public ConcurrentDictionary entityCache; public ConcurrentBag modelsInUse; public EnumerableLruCache> embeddingCache; - private readonly MySqlConnection connection; public SQLHelper helper; private readonly ILogger _logger; - public Searchdomain(string searchdomain, string connectionString, AIProvider aIProvider, EnumerableLruCache> embeddingCache, ILogger logger, string provider = "sqlserver", bool runEmpty = false) + public Searchdomain(string searchdomain, string connectionString, SQLHelper sqlHelper, AIProvider aIProvider, EnumerableLruCache> embeddingCache, ILogger logger, string provider = "sqlserver", bool runEmpty = false) { _connectionString = connectionString; _provider = provider.ToLower(); @@ -36,9 +35,7 @@ public class Searchdomain this.embeddingCache = embeddingCache; this._logger = logger; entityCache = []; - connection = new MySqlConnection(connectionString); - connection.Open(); - helper = new SQLHelper(connection, connectionString); + helper = sqlHelper; settings = GetSettings(); queryCache = new(settings.QueryCacheSize); modelsInUse = []; // To make the compiler shut up - it is set in UpdateSearchDomain() don't worry // yeah, about that... diff --git a/src/Server/SearchdomainManager.cs b/src/Server/SearchdomainManager.cs index 47ebada..266ee93 100644 --- a/src/Server/SearchdomainManager.cs +++ b/src/Server/SearchdomainManager.cs @@ -58,7 +58,7 @@ public class SearchdomainManager : IDisposable } try { - return SetSearchdomain(searchdomain, new Searchdomain(searchdomain, connectionString, aIProvider, embeddingCache, _logger)); + return SetSearchdomain(searchdomain, new Searchdomain(searchdomain, connectionString, helper, aIProvider, embeddingCache, _logger)); } catch (MySqlException) { @@ -101,7 +101,9 @@ public class SearchdomainManager : IDisposable { "name", searchdomain }, { "settings", settings} }; - return await helper.ExecuteSQLCommandGetInsertedID("INSERT INTO searchdomain (name, settings) VALUES (@name, @settings)", parameters); + int id = await helper.ExecuteSQLCommandGetInsertedID("INSERT INTO searchdomain (name, settings) VALUES (@name, @settings)", parameters); + searchdomains.Add(searchdomain, new(searchdomain, connectionString, helper, aIProvider, embeddingCache, _logger)); + return id; } public async Task DeleteSearchdomain(string searchdomain)