using System.Text.Json; using Moonlight.Shared.Http; using Moonlight.Shared.Http.Events; namespace Moonlight.Api.Services; public class ContainerHelperService { private readonly IHttpClientFactory HttpClientFactory; public ContainerHelperService(IHttpClientFactory httpClientFactory) { HttpClientFactory = httpClientFactory; } public async Task CheckConnectionAsync() { var client = HttpClientFactory.CreateClient("ContainerHelper"); try { var response = await client.GetAsync("api/ping"); response.EnsureSuccessStatusCode(); return true; } catch (Exception) { return false; } } public async IAsyncEnumerable RebuildAsync() { var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }; options.TypeInfoResolverChain.Add(SerializationContext.Default); var client = HttpClientFactory.CreateClient("ContainerHelper"); var response = await client.GetAsync("api/rebuild", HttpCompletionOption.ResponseHeadersRead); if (!response.IsSuccessStatusCode) { var responseText = await response.Content.ReadAsStringAsync(); yield return new RebuildEvent() { Type = RebuildEventType.Failed, Data = responseText }; yield break; } await using var responseStream = await response.Content.ReadAsStreamAsync(); using var streamReader = new StreamReader(responseStream); do { var line = await streamReader.ReadLineAsync(); if(line == null) break; if(string.IsNullOrWhiteSpace(line)) continue; var data = line.Trim("data: "); var deserializedData = JsonSerializer.Deserialize(data, options); yield return deserializedData; // Exit if service will go down for a clean exit if(deserializedData is {Type: RebuildEventType.Step, Data: "ServiceDown"}) yield break; } while (true); yield return new RebuildEvent() { Type = RebuildEventType.Succeeded, Data = string.Empty }; } }