diff --git a/Libplanet.Explorer.Executable/Program.cs b/Libplanet.Explorer.Executable/Program.cs index 32c33cbae0b..94420e6211e 100644 --- a/Libplanet.Explorer.Executable/Program.cs +++ b/Libplanet.Explorer.Executable/Program.cs @@ -24,7 +24,7 @@ namespace Libplanet.Explorer.Executable /// public class Program { - public static void Main(string[] args) + public static async Task Main(string[] args) { Options options = Options.Parse(args, Console.Error); @@ -38,7 +38,11 @@ public static void Main(string[] args) .WriteTo.Console(); Log.Logger = loggerConfig.CreateLogger(); - IStore store = new LiteDBStore(options.StorePath, readOnly: options.Seed is null); + IStore store = new LiteDBStore( + path: options.StorePath, + flush: false, + readOnly: options.Seed is null + ); IBlockPolicy policy = new BlockPolicy( null, blockIntervalMilliseconds: options.BlockIntervalMilliseconds, @@ -47,6 +51,12 @@ public static void Main(string[] args) var blockChain = new BlockChain(policy, store); Startup.BlockChainSingleton = blockChain; + IWebHost webHost = WebHost.CreateDefaultBuilder() + .UseStartup>() + .UseSerilog() + .UseUrls($"http://{options.Host}:{options.Port}/") + .Build(); + Swarm swarm = null; if (options.Seed is BoundPeer) { @@ -71,76 +81,71 @@ public static void Main(string[] args) ); } - IWebHost webHost = WebHost.CreateDefaultBuilder() - .UseStartup>() - .UseSerilog() - .UseUrls($"http://{options.Host}:{options.Port}/") - .Build(); - - var cts = new CancellationTokenSource(); - Console.CancelKeyPress += (sender, eventArgs) => + using (var cts = new CancellationTokenSource()) + using (swarm) { - eventArgs.Cancel = true; - cts.Cancel(); - }; + Console.CancelKeyPress += (sender, eventArgs) => + { + eventArgs.Cancel = true; + cts.Cancel(); + }; - Task swarmTask = Task.Run( - async () => + try { - if (swarm is null) - { - return; - } - - var peers = new HashSet(); - if (options.Seed is Peer peer) - { - peers.Add(peer); - } - - try - { - await swarm.BootstrapAsync( - peers, - 5000, - 5000, - cancellationToken: cts.Token - ); - } - catch (TimeoutException) - { - Console.Error.WriteLine("No any neighbors."); - } - - // Since explorer does not require states, turn off trustedPeer option. - /*ImmutableHashSet
trustedPeers = - peers.Select(p => p.Address).ToImmutableHashSet();*/ - var trustedPeers = ImmutableHashSet
.Empty; - Console.Error.WriteLine("Starts preloading."); - await swarm.PreloadAsync( - dialTimeout: TimeSpan.FromSeconds(15), - trustedStateValidators: trustedPeers, - cancellationToken: cts.Token + await Task.WhenAll( + webHost.RunAsync(cts.Token), + StartSwarmAsync(swarm, options.Seed, cts.Token) ); - Console.Error.WriteLine("Finished preloading."); + } + catch (OperationCanceledException) + { + await swarm?.StopAsync(waitFor: TimeSpan.FromSeconds(1)) + .ContinueWith(_ => NetMQConfig.Cleanup(false)); + } + } + } - await swarm.StartAsync(cancellationToken: cts.Token); - }, - cts.Token - ); + private static async Task StartSwarmAsync( + Swarm swarm, + Peer seed, + CancellationToken cancellationToken) + { + if (swarm is null) + { + return; + } + + var peers = new HashSet(); + if (!(seed is null)) + { + peers.Add(seed); + } try { - Task.WaitAll(webHost.RunAsync(cts.Token), swarmTask); + await swarm.BootstrapAsync( + peers, + 5000, + 5000, + cancellationToken: cancellationToken + ); } - catch (OperationCanceledException) + catch (TimeoutException) { - if (swarm is Swarm) - { - Task.WaitAll(swarm.StopAsync(waitFor: TimeSpan.FromSeconds(1))); - NetMQConfig.Cleanup(false); - } + Console.Error.WriteLine("No any neighbors."); } + + // Since explorer does not require states, turn off trustedPeer option. + var trustedPeers = ImmutableHashSet
.Empty; + Console.Error.WriteLine("Starts preloading."); + await swarm.PreloadAsync( + dialTimeout: TimeSpan.FromSeconds(15), + trustedStateValidators: trustedPeers, + cancellationToken: cancellationToken + ); + Console.Error.WriteLine("Finished preloading."); + + await swarm.StartAsync(cancellationToken: cancellationToken); } internal class AppAgnosticAction : IAction