Skip to content

Commit

Permalink
Merge pull request #97 from s2quake/feature/content-dependency
Browse files Browse the repository at this point in the history
Introduce topology sorting for node and client content
  • Loading branch information
s2quake authored Dec 1, 2024
2 parents f879ba3 + 3fb9c3d commit 9ab364f
Show file tree
Hide file tree
Showing 14 changed files with 51 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ obj/
.DS_Store
.vs/
.bin/
.submodules/
test-results.trx
2 changes: 2 additions & 0 deletions src/client/LibplanetConsole.Client/ClientContentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ protected ClientContentBase()

public string Name => _name != string.Empty ? _name : GetType().Name;

public virtual IEnumerable<IClientContent> Dependencies => [];

void IDisposable.Dispose()
{
OnDispose(disposing: true);
Expand Down
9 changes: 8 additions & 1 deletion src/client/LibplanetConsole.Client/ClientHostedService.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using LibplanetConsole.Common;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

Expand All @@ -9,7 +10,7 @@ internal sealed class ClientHostedService(
{
public async Task StartAsync(CancellationToken cancellationToken)
{
client.Contents = [.. serviceProvider.GetServices<IClientContent>()];
client.Contents = GetClientContents(serviceProvider);
if (options.NodeEndPoint is not null)
{
client.NodeEndPoint = options.NodeEndPoint;
Expand All @@ -24,4 +25,10 @@ public async Task StopAsync(CancellationToken cancellationToken)
await client.StopAsync(cancellationToken);
}
}

private static IClientContent[] GetClientContents(IServiceProvider serviceProvider)
{
var contents = serviceProvider.GetServices<IClientContent>();
return [.. DependencyUtility.TopologicalSort(contents, content => content.Dependencies)];
}
}
2 changes: 2 additions & 0 deletions src/client/LibplanetConsole.Client/IClientContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public interface IClientContent
{
string Name { get; }

IEnumerable<IClientContent> Dependencies { get; }

Task StartAsync(CancellationToken cancellationToken);

Task StopAsync(CancellationToken cancellationToken);
Expand Down
2 changes: 2 additions & 0 deletions src/console/LibplanetConsole.Console/ClientContentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ protected ClientContentBase()

public string Name => _name != string.Empty ? _name : GetType().Name;

public virtual IEnumerable<IClientContent> Dependencies => [];

void IDisposable.Dispose()
{
OnDispose(disposing: true);
Expand Down
9 changes: 8 additions & 1 deletion src/console/LibplanetConsole.Console/ClientFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using LibplanetConsole.Common;
using Microsoft.Extensions.DependencyInjection;

namespace LibplanetConsole.Console;
Expand Down Expand Up @@ -46,10 +47,16 @@ public static Client CreateNew(IServiceProvider serviceProvider, ClientOptions c
var scopedServiceProvider = serviceScope.ServiceProvider;
var key = IClient.Key;
var client = scopedServiceProvider.GetRequiredKeyedService<Client>(key);
client.Contents = [.. scopedServiceProvider.GetKeyedServices<IClientContent>(key)];
client.Contents = GetClientContents(scopedServiceProvider, key);
return client;
}

private static IClientContent[] GetClientContents(IServiceProvider serviceProvider, string key)
{
var contents = serviceProvider.GetKeyedServices<IClientContent>(key);
return [.. DependencyUtility.TopologicalSort(contents, content => content.Dependencies)];
}

private sealed record class Descriptor
{
public required ClientOptions ClientOptions { get; init; }
Expand Down
2 changes: 2 additions & 0 deletions src/console/LibplanetConsole.Console/IClientContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public interface IClientContent
{
string Name { get; }

IEnumerable<IClientContent> Dependencies { get; }

Task StartAsync(CancellationToken cancellationToken);

Task StopAsync(CancellationToken cancellationToken);
Expand Down
2 changes: 2 additions & 0 deletions src/console/LibplanetConsole.Console/INodeContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public interface INodeContent
{
string Name { get; }

IEnumerable<INodeContent> Dependencies { get; }

Task StartAsync(CancellationToken cancellationToken);

Task StopAsync(CancellationToken cancellationToken);
Expand Down
2 changes: 2 additions & 0 deletions src/console/LibplanetConsole.Console/NodeContentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ protected NodeContentBase()

public string Name => _name != string.Empty ? _name : GetType().Name;

public virtual IEnumerable<INodeContent> Dependencies => [];

void IDisposable.Dispose()
{
OnDispose(disposing: true);
Expand Down
9 changes: 8 additions & 1 deletion src/console/LibplanetConsole.Console/NodeFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using LibplanetConsole.Common;
using Microsoft.Extensions.DependencyInjection;

namespace LibplanetConsole.Console;
Expand Down Expand Up @@ -46,10 +47,16 @@ public static Node CreateNew(IServiceProvider serviceProvider, NodeOptions nodeO
var scopedServiceProvider = serviceScope.ServiceProvider;
var key = INode.Key;
var node = scopedServiceProvider.GetRequiredKeyedService<Node>(key);
node.Contents = [.. scopedServiceProvider.GetKeyedServices<INodeContent>(key)];
node.Contents = GetNodeContents(scopedServiceProvider, key);
return node;
}

private static INodeContent[] GetNodeContents(IServiceProvider serviceProvider, string key)
{
var contents = serviceProvider.GetKeyedServices<INodeContent>(key);
return [.. DependencyUtility.TopologicalSort(contents, content => content.Dependencies)];
}

private sealed record class Descriptor
{
public required NodeOptions NodeOptions { get; init; }
Expand Down
2 changes: 2 additions & 0 deletions src/node/LibplanetConsole.Node.Evidence/Evidence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ internal sealed class Evidence(INode node) : IEvidence, INodeContent, IAsyncDisp

public string Name => nameof(Evidence);

public IEnumerable<INodeContent> Dependencies => [];

public async Task<EvidenceInfo> AddEvidenceAsync(CancellationToken cancellationToken)
{
var blockChain = node.GetRequiredService<BlockChain>();
Expand Down
2 changes: 2 additions & 0 deletions src/node/LibplanetConsole.Node/INodeContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public interface INodeContent
{
string Name { get; }

IEnumerable<INodeContent> Dependencies { get; }

Task StartAsync(CancellationToken cancellationToken);

Task StopAsync(CancellationToken cancellationToken);
Expand Down
2 changes: 2 additions & 0 deletions src/node/LibplanetConsole.Node/NodeContentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public abstract class NodeContentBase(string name) : INodeContent, IDisposable

public string Name => _name != string.Empty ? _name : GetType().Name;

public virtual IEnumerable<INodeContent> Dependencies => [];

void IDisposable.Dispose()
{
OnDispose(disposing: true);
Expand Down
9 changes: 8 additions & 1 deletion src/node/LibplanetConsole.Node/NodeHostedService.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using LibplanetConsole.Common;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

Expand All @@ -9,7 +10,7 @@ internal sealed class NodeHostedService(
{
public async Task StartAsync(CancellationToken cancellationToken)
{
node.Contents = [.. serviceProvider.GetServices<INodeContent>()];
node.Contents = GetNodeContents(serviceProvider);
if (options.SeedEndPoint is not null || options.IsSingleNode is true)
{
node.SeedEndPoint = options.SeedEndPoint;
Expand All @@ -24,4 +25,10 @@ public async Task StopAsync(CancellationToken cancellationToken)
await node.StopAsync(cancellationToken);
}
}

private static INodeContent[] GetNodeContents(IServiceProvider serviceProvider)
{
var contents = serviceProvider.GetServices<INodeContent>();
return [.. DependencyUtility.TopologicalSort(contents, content => content.Dependencies)];
}
}

0 comments on commit 9ab364f

Please sign in to comment.