zcbot/windows-node/Zcbot.WindowsNode/Adapters/AdapterCatalog.cs

60 lines
2.3 KiB
C#

namespace Zcbot.WindowsNode;
internal sealed class AdapterCatalog
{
private static readonly Lazy<IReadOnlyList<AdapterDescriptor>> InstalledDescriptors =
new(DiscoverDescriptors, LazyThreadSafetyMode.ExecutionAndPublication);
private static readonly JobExecutionGate SharedExecutionGate = new();
private static readonly ProcessSupervisor SharedProcessSupervisor = new();
private readonly IReadOnlyDictionary<string, INodeAdapter> adapters;
internal AdapterCatalog(IEnumerable<INodeAdapter> values)
{
adapters = values.ToDictionary(item => item.Capability, StringComparer.Ordinal);
}
internal static string AdapterRoot =>
Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "adapters"));
internal static AdapterCatalog CreateDefault(
JobRepository inbox,
NodePaths? paths = null)
{
var resolvedPaths = paths ?? NodePaths.ForCurrentMachine();
return new(InstalledDescriptors.Value.Select(item => new ProcessNodeAdapter(
item, inbox, resolvedPaths, SharedExecutionGate, SharedProcessSupervisor)));
}
internal static IReadOnlyList<NodeAdapterContract> InstalledContracts =>
InstalledDescriptors.Value.Select(item => item.Contract).ToArray();
internal static IReadOnlyList<string> InstalledCapabilities =>
InstalledContracts.Select(item => item.Capability).ToArray();
internal static bool HasActiveExecution => SharedExecutionGate.IsActive;
internal IReadOnlyCollection<INodeAdapter> All => adapters.Values.ToArray();
internal INodeAdapter? Find(string capability) =>
adapters.TryGetValue(capability, out var adapter) ? adapter : null;
internal void InvalidateRuntime(string runtimeId)
{
foreach (var adapter in adapters.Values.Where(
item => runtimeId.Equals(item.RuntimeId, StringComparison.Ordinal)))
{
adapter.InvalidateRuntime();
}
}
private static IReadOnlyList<AdapterDescriptor> DiscoverDescriptors()
{
if (!Directory.Exists(AdapterRoot)) return [];
return Directory.EnumerateDirectories(AdapterRoot)
.Where(path => File.Exists(Path.Combine(path, "adapter.json")))
.OrderBy(path => path, StringComparer.OrdinalIgnoreCase)
.Select(AdapterContractLoader.Load)
.ToArray();
}
}