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 k8s;
using Logging; using Logging;
using Utils;
namespace KubernetesWorkflow namespace KubernetesWorkflow
{ {
public class ContainerCrashWatcher : ICrashWatcher public class ContainerCrashWatcher
{ {
private readonly ILog log; private readonly ILog log;
private readonly KubernetesClientConfiguration config; private readonly KubernetesClientConfiguration config;

View File

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

View File

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

View File

@ -34,6 +34,7 @@ namespace CodexClient
Address GetDiscoveryEndpoint(); Address GetDiscoveryEndpoint();
Address GetApiEndpoint(); Address GetApiEndpoint();
Address GetListenEndpoint(); Address GetListenEndpoint();
Address GetMetricsScrapeTarget();
/// <summary> /// <summary>
/// Warning! The node is not usable after this. /// Warning! The node is not usable after this.
@ -85,16 +86,6 @@ namespace CodexClient
public DebugInfoVersion Version { get; private set; } public DebugInfoVersion Version { get; private set; }
public ITransferSpeeds TransferSpeeds { get => transferSpeeds; } 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 public EthAddress EthAddress
{ {
get get
@ -278,9 +269,16 @@ namespace CodexClient
return codexAccess.GetListenEndpoint(); 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() public bool HasCrashed()
{ {
return codexAccess.CrashWatcher.HasCrashed(); return codexAccess.HasCrashed();
} }
public override string ToString() 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 namespace CodexClient
{ {
public interface IIProcessControlFactory
{
IProcessControl CreateProcessControl(ICodexInstance instance);
}
public interface IProcessControl public interface IProcessControl
{ {
void Stop(ICodexInstance instance, bool waitTillStopped); void Stop(bool waitTillStopped);
IDownloadedLog DownloadLog(ICodexInstance instance, LogFile file); IDownloadedLog DownloadLog(LogFile file);
void DeleteDataDirFolder(ICodexInstance instance); void DeleteDataDirFolder();
bool HasCrashed();
} }
} }

View File

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

View File

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

View File

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

View File

@ -5,8 +5,8 @@ using Logging;
using Nethereum.ABI.FunctionEncoding.Attributes; using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.Contracts; using Nethereum.Contracts;
using Nethereum.Hex.HexConvertors.Extensions; using Nethereum.Hex.HexConvertors.Extensions;
using NethereumWorkflow;
using System.Numerics; using System.Numerics;
using Utils;
namespace CodexContractsPlugin 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. #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
using BlockchainUtils; using BlockchainUtils;
using GethPlugin;
using Newtonsoft.Json; using Newtonsoft.Json;
using Utils;
namespace CodexContractsPlugin.Marketplace 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 MetricsPlugin;
using System.Collections; using System.Collections;
using Utils; using Utils;
@ -41,7 +42,7 @@ namespace CodexPlugin
public ICodexNode[] Nodes => nodes; public ICodexNode[] Nodes => nodes;
public DebugInfoVersion Version { get; private set; } 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() public IEnumerator<ICodexNode> GetEnumerator()
{ {

View File

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

View File

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

View File

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