This commit is contained in:
ThatBen 2025-01-16 13:24:57 +01:00
parent 4a151880d4
commit c73fa186fc
No known key found for this signature in database
GPG Key ID: 62C543548433D43E
16 changed files with 96 additions and 85 deletions

View File

@ -1,10 +1,9 @@
using k8s;
using Logging;
using Utils;
namespace KubernetesWorkflow
{
public class ContainerCrashWatcher : ICrashWatcher
public class ContainerCrashWatcher
{
private readonly ILog log;
private readonly KubernetesClientConfiguration config;

View File

@ -1,9 +1,9 @@
namespace Utils
{
public interface ICrashWatcher
{
void Start();
void Stop();
bool HasCrashed();
}
//public interface ICrashWatcher
//{
// void Start();
// void Stop();
// bool HasCrashed();
//}
}

View File

@ -14,30 +14,24 @@ namespace CodexClient
private ICodexInstance instance;
private readonly Mapper mapper = new Mapper();
public CodexAccess(ILog log, IHttpFactory httpFactory, IProcessControl processControl, ICodexInstance instance, ICrashWatcher crashWatcher)
public CodexAccess(ILog log, IHttpFactory httpFactory, IProcessControl processControl, ICodexInstance instance)
{
this.log = log;
this.httpFactory = httpFactory;
this.processControl = processControl;
this.instance = instance;
CrashWatcher = crashWatcher;
CrashWatcher.Start();
}
public ICrashWatcher CrashWatcher { get; }
public void Stop(bool waitTillStopped)
{
CrashWatcher.Stop();
processControl.Stop(instance, waitTillStopped);
processControl.Stop(waitTillStopped);
// Prevents accidental use after stop:
instance = null!;
}
public IDownloadedLog DownloadLog(string additionalName = "")
{
return processControl.DownloadLog(instance, log.CreateSubfile(GetName() + additionalName));
return processControl.DownloadLog(log.CreateSubfile(GetName() + additionalName));
}
public string GetImageName()
@ -205,6 +199,11 @@ namespace CodexClient
return instance.ListenEndpoint;
}
public bool HasCrashed()
{
return processControl.HasCrashed();
}
public Address? GetMetricsEndpoint()
{
return instance.MetricsEndpoint;
@ -217,18 +216,18 @@ namespace CodexClient
public void DeleteDataDirFolder()
{
processControl.DeleteDataDirFolder(instance);
processControl.DeleteDataDirFolder();
}
private T OnCodex<T>(Func<openapiClient, Task<T>> action)
{
var result = httpFactory.CreateHttp(GetHttpId(), CheckContainerCrashed).OnClient(client => CallCodex(client, action));
var result = httpFactory.CreateHttp(GetHttpId(), h => CheckContainerCrashed()).OnClient(client => CallCodex(client, action));
return result;
}
private T OnCodex<T>(Func<openapiClient, Task<T>> action, Retry retry)
{
var result = httpFactory.CreateHttp(GetHttpId(), CheckContainerCrashed).OnClient(client => CallCodex(client, action), retry);
var result = httpFactory.CreateHttp(GetHttpId(), h => CheckContainerCrashed()).OnClient(client => CallCodex(client, action), retry);
return result;
}
@ -248,14 +247,14 @@ namespace CodexClient
}
finally
{
CrashWatcher.HasCrashed();
CheckContainerCrashed();
}
}
private IEndpoint GetEndpoint()
{
return httpFactory
.CreateHttp(GetHttpId(), CheckContainerCrashed)
.CreateHttp(GetHttpId(), h => CheckContainerCrashed())
.CreateEndpoint(GetAddress(), "/api/codex/v1/", GetName());
}
@ -269,9 +268,9 @@ namespace CodexClient
return GetAddress().ToString();
}
private void CheckContainerCrashed(HttpClient client)
private void CheckContainerCrashed()
{
if (CrashWatcher.HasCrashed()) throw new Exception($"Container {GetName()} has crashed.");
if (processControl.HasCrashed()) throw new Exception($"Container {GetName()} has crashed.");
}
private void Throw(Failure failure)

View File

@ -34,6 +34,7 @@ namespace CodexClient
Address GetDiscoveryEndpoint();
Address GetApiEndpoint();
Address GetListenEndpoint();
Address GetMetricsScrapeTarget();
/// <summary>
/// Warning! The node is not usable after this.
@ -85,16 +86,6 @@ namespace CodexClient
public DebugInfoVersion Version { get; private set; }
public ITransferSpeeds TransferSpeeds { get => transferSpeeds; }
public Address MetricsScrapeTarget
{
get
{
var address = codexAccess.GetMetricsEndpoint();
if (address == null) throw new Exception("Metrics ScrapeTarget accessed, but node was not started with EnableMetrics()");
return address;
}
}
public EthAddress EthAddress
{
get
@ -278,9 +269,16 @@ namespace CodexClient
return codexAccess.GetListenEndpoint();
}
public Address GetMetricsScrapeTarget()
{
var address = codexAccess.GetMetricsEndpoint();
if (address == null) throw new Exception("Metrics ScrapeTarget accessed, but node was not started with EnableMetrics()");
return address;
}
public bool HasCrashed()
{
return codexAccess.CrashWatcher.HasCrashed();
return codexAccess.HasCrashed();
}
public override string ToString()

View File

@ -0,0 +1,40 @@
using CodexClient.Hooks;
using FileUtils;
using Logging;
using WebUtils;
namespace CodexClient
{
public class CodexNodeFactory
{
private readonly ILog log;
private readonly IFileManager fileManager;
private readonly ICodexHooksProvider hooksProvider;
private readonly IHttpFactory httpFactory;
private readonly IIProcessControlFactory processControlFactory;
public CodexNodeFactory(ILog log, IFileManager fileManager, ICodexHooksProvider hooksProvider, IHttpFactory httpFactory, IIProcessControlFactory processControlFactory)
{
this.log = log;
this.fileManager = fileManager;
this.hooksProvider = hooksProvider;
this.httpFactory = httpFactory;
this.processControlFactory = processControlFactory;
}
public ICodexNode CreateCodexNode(ICodexInstance instance)
{
var processControl = processControlFactory.CreateProcessControl(instance);
var access = new CodexAccess(log, httpFactory, processControl, instance);
var hooks = hooksProvider.CreateHooks(access.GetName());
var marketplaceAccess = CreateMarketplaceAccess(instance, access, hooks);
return new CodexNode(log, access, fileManager, marketplaceAccess, hooks);
}
private IMarketplaceAccess CreateMarketplaceAccess(ICodexInstance instance, CodexAccess access, ICodexNodeHooks hooks)
{
if (instance.EthAccount == null) return new MarketplaceUnavailable();
return new MarketplaceAccess(log, access, hooks);
}
}
}

View File

@ -2,10 +2,16 @@
namespace CodexClient
{
public interface IIProcessControlFactory
{
IProcessControl CreateProcessControl(ICodexInstance instance);
}
public interface IProcessControl
{
void Stop(ICodexInstance instance, bool waitTillStopped);
IDownloadedLog DownloadLog(ICodexInstance instance, LogFile file);
void DeleteDataDirFolder(ICodexInstance instance);
void Stop(bool waitTillStopped);
IDownloadedLog DownloadLog(LogFile file);
void DeleteDataDirFolder();
bool HasCrashed();
}
}

View File

@ -1,5 +1,5 @@
using GethPlugin;
using System.Numerics;
using System.Numerics;
using Utils;
namespace CodexContractsPlugin.ChainMonitor
{

View File

@ -1,6 +1,6 @@
using CodexContractsPlugin.Marketplace;
using GethPlugin;
using Logging;
using Utils;
namespace CodexContractsPlugin.ChainMonitor
{

View File

@ -1,5 +1,5 @@
using GethPlugin;
using System.Numerics;
using System.Numerics;
using Utils;
namespace CodexContractsPlugin.ChainMonitor
{

View File

@ -5,8 +5,8 @@ using Logging;
using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.Contracts;
using Nethereum.Hex.HexConvertors.Extensions;
using NethereumWorkflow;
using System.Numerics;
using Utils;
namespace CodexContractsPlugin
{

View File

@ -1,7 +1,7 @@
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
using BlockchainUtils;
using GethPlugin;
using Newtonsoft.Json;
using Utils;
namespace CodexContractsPlugin.Marketplace
{

View File

@ -1,35 +0,0 @@
using CodexPlugin.Hooks;
using Core;
namespace CodexPlugin
{
public interface ICodexNodeFactory
{
CodexNode CreateOnlineCodexNode(CodexAccess access);
}
public class CodexNodeFactory : ICodexNodeFactory
{
private readonly IPluginTools tools;
private readonly CodexHooksFactory codexHooksFactory;
public CodexNodeFactory(IPluginTools tools, CodexHooksFactory codexHooksFactory)
{
this.tools = tools;
this.codexHooksFactory = codexHooksFactory;
}
public CodexNode CreateOnlineCodexNode(CodexAccess access)
{
var hooks = codexHooksFactory.CreateHooks(access.GetName());
var marketplaceAccess = GetMarketplaceAccess(access, hooks);
return new CodexNode(tools, access, marketplaceAccess, hooks);
}
private IMarketplaceAccess GetMarketplaceAccess(CodexAccess codexAccess, ICodexNodeHooks hooks)
{
if (codexAccess.GetEthAccount() == null) return new MarketplaceUnavailable();
return new MarketplaceAccess(tools.GetLog(), codexAccess, hooks);
}
}
}

View File

@ -1,4 +1,5 @@
using Core;
using CodexClient;
using Core;
using MetricsPlugin;
using System.Collections;
using Utils;
@ -41,7 +42,7 @@ namespace CodexPlugin
public ICodexNode[] Nodes => nodes;
public DebugInfoVersion Version { get; private set; }
public Address[] ScrapeTargets => Nodes.Select(n => n.MetricsScrapeTarget).ToArray();
public Address[] ScrapeTargets => Nodes.Select(n => n.GetMetricsScrapeTarget()).ToArray();
public IEnumerator<ICodexNode> GetEnumerator()
{

View File

@ -1,4 +1,5 @@
using CodexPlugin.Hooks;
using CodexClient;
using CodexClient.Hooks;
using Core;
using KubernetesWorkflow.Types;

View File

@ -1,4 +1,5 @@
using CodexContractsPlugin;
using CodexClient;
using CodexContractsPlugin;
using GethPlugin;
using KubernetesWorkflow;
using Utils;
@ -223,7 +224,7 @@ namespace CodexPlugin
{
if (pinned) return accounts.Last();
var a = EthAccount.GenerateNew();
var a = EthAccountGenerator.GenerateNew();
accounts.Add(a);
return a;
}

View File

@ -4,6 +4,7 @@ using KubernetesWorkflow.Types;
using Logging;
using System.Globalization;
using Utils;
using WebUtils;
namespace MetricsPlugin
{