diff --git a/README.md b/README.md index c7d0f88f..c656cf41 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,6 @@ services: AKKA__CLUSTER__SPLIT_BRAIN_RESOLVER__ACTIVE_STRATEGY: "keep-majority" ``` -### Running in .NET Framework -You can still run Lighthouse under .NET Framework 4.6.1 if you wish. Clone this repository and build the project. Lighthouse will run as a [Topshelf Windows Service](http://topshelf-project.com/) and can be installed as such. - ### Examples of Lighthouse in the Wild Looking for some complete examples of how to use Lighthouse? Here's some: diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 796bdcf5..bd8598c9 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,9 +1,5 @@ -#### 1.5.5 June 16 2021 #### -* Upgrade [Akka.Bootstrap.Docker to 0.5.3](https://github.com/petabridge/akkadotnet-bootstrap/releases/tag/0.5.3) +#### 1.6.0 April 18 2022 #### -#### 1.5.4 June 16 2021 #### -* Upgraded to [Akka.NET v1.4.21](https://github.com/akkadotnet/akka.net/releases/tag/1.4.21) - -#### 1.5.3 May 10 2021 #### -* Upgraded to [Akka.NET v1.4.19](https://github.com/akkadotnet/akka.net/releases/tag/1.4.19) -* Upgraded to [Petabridge.Cmd v0.8.5](https://cmd.petabridge.com/articles/RELEASE_NOTES.html#085-may-03-2021) +* Dropped Topshelf support +* Migrated to [Akka.Hosting](https://github.com/akkadotnet/Akka.Hosting) and `IHostedService` +* Significantly reduced idle CPU consumption by migrating to [`channel-executor` for dispatching](https://getakka.net/articles/actors/dispatchers.html#channelexecutor). \ No newline at end of file diff --git a/build-system/linux-pr-validation.yaml b/build-system/linux-pr-validation.yaml index d1ec21ec..cd42e67f 100644 --- a/build-system/linux-pr-validation.yaml +++ b/build-system/linux-pr-validation.yaml @@ -17,6 +17,6 @@ jobs: - template: azure-pipeline.template.yaml parameters: name: Ubuntu - vmImage: 'ubuntu-16.04' + vmImage: 'ubuntu-20.04' scriptFileName: ./build.sh - scriptArgs: all \ No newline at end of file + scriptArgs: all diff --git a/src/Lighthouse/Lighthouse.csproj b/src/Lighthouse/Lighthouse.csproj index 2e3f570f..5a9cf362 100644 --- a/src/Lighthouse/Lighthouse.csproj +++ b/src/Lighthouse/Lighthouse.csproj @@ -2,11 +2,11 @@ Exe - $(NetCoreVersion);$(NetFrameworkLibVersion) + $(NetCoreVersion) - - + + @@ -14,17 +14,9 @@ - - - - - - $(DefineConstants);CORECLR - - PreserveNewest - \ No newline at end of file + diff --git a/src/Lighthouse/LighthouseHostFactory.cs b/src/Lighthouse/LighthouseConfigurator.cs old mode 100755 new mode 100644 similarity index 76% rename from src/Lighthouse/LighthouseHostFactory.cs rename to src/Lighthouse/LighthouseConfigurator.cs index c3fb11ad..7687475f --- a/src/Lighthouse/LighthouseHostFactory.cs +++ b/src/Lighthouse/LighthouseConfigurator.cs @@ -1,5 +1,5 @@ // ----------------------------------------------------------------------- -// +// // Copyright (C) 2015 - 2019 Petabridge, LLC // // ----------------------------------------------------------------------- @@ -15,22 +15,20 @@ namespace Lighthouse { /// - /// Launcher for the Lighthouse + /// Configurator for Lighthouse /// - public static class LighthouseHostFactory + public static class LighthouseConfigurator { - public static ActorSystem LaunchLighthouse(string ipAddress = null, int? specifiedPort = null, + public static (Config config, string actorSystemName) LaunchLighthouse(string ipAddress = null, int? specifiedPort = null, string systemName = null) { systemName = systemName ?? Environment.GetEnvironmentVariable("ACTORSYSTEM")?.Trim(); - - // Set environment variables for use inside Akka.Bootstrap.Docker - // If overrides were provided to this method. - //if (!string.IsNullOrEmpty(ipAddress)) Environment.SetEnvironmentVariable("CLUSTER_IP", ipAddress); - - //if (specifiedPort != null) - // Environment.SetEnvironmentVariable("CLUSTER_PORT", specifiedPort.Value.ToString()); + var argConfig = ""; + if (ipAddress != null) + argConfig += $"akka.remote.dot-netty.tcp.public-hostname = {ipAddress}\n"; + if (specifiedPort != null) + argConfig += $"akka.remote.dot-netty.tcp.port = {specifiedPort}"; var useDocker = !(IsNullOrEmpty(Environment.GetEnvironmentVariable("CLUSTER_IP")?.Trim()) || IsNullOrEmpty(Environment.GetEnvironmentVariable("CLUSTER_SEEDS")?.Trim())); @@ -41,6 +39,11 @@ public static ActorSystem LaunchLighthouse(string ipAddress = null, int? specifi if (useDocker) clusterConfig = clusterConfig.BootstrapFromDocker(); + // Values from method arguments should always win + if (!IsNullOrEmpty(argConfig)) + clusterConfig = ConfigurationFactory.ParseString(argConfig) + .WithFallback(clusterConfig); + var lighthouseConfig = clusterConfig.GetConfig("lighthouse"); if (lighthouseConfig != null && IsNullOrEmpty(systemName)) systemName = lighthouseConfig.GetString("actorsystem", systemName); @@ -88,7 +91,7 @@ public static ActorSystem LaunchLighthouse(string ipAddress = null, int? specifi .WithFallback(clusterConfig) : clusterConfig; - return ActorSystem.Create(systemName, finalConfig); + return (finalConfig, systemName); } } } \ No newline at end of file diff --git a/src/Lighthouse/LighthouseService.cs b/src/Lighthouse/LighthouseService.cs deleted file mode 100755 index c00ae40c..00000000 --- a/src/Lighthouse/LighthouseService.cs +++ /dev/null @@ -1,56 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (C) 2015 - 2019 Petabridge, LLC -// -// ----------------------------------------------------------------------- - -using System.Threading.Tasks; -using Akka.Actor; -using Petabridge.Cmd.Cluster; -using Petabridge.Cmd.Host; -using Petabridge.Cmd.Remote; - -namespace Lighthouse -{ - public class LighthouseService - { - private readonly string _actorSystemName; - private readonly string _ipAddress; - private readonly int? _port; - - private ActorSystem _lighthouseSystem; - - public LighthouseService() : this(null, null, null) - { - } - - public LighthouseService(string ipAddress, int? port, string actorSystemName) - { - _ipAddress = ipAddress; - _port = port; - _actorSystemName = actorSystemName; - } - - /// - /// Task completes once the Lighthouse has terminated. - /// - /// - /// Doesn't actually invoke termination. Need to call for that. - /// - public Task TerminationHandle => _lighthouseSystem.WhenTerminated; - - public void Start() - { - _lighthouseSystem = LighthouseHostFactory.LaunchLighthouse(_ipAddress, _port, _actorSystemName); - var pbm = PetabridgeCmd.Get(_lighthouseSystem); - pbm.RegisterCommandPalette(ClusterCommands.Instance); // enable Akka.Cluster management commands - pbm.RegisterCommandPalette(RemoteCommands.Instance); // enable Akka.Remote management commands - pbm.Start(); - } - - public async Task StopAsync() - { - await CoordinatedShutdown.Get(_lighthouseSystem).Run(CoordinatedShutdown.ClrExitReason.Instance); - } - } -} \ No newline at end of file diff --git a/src/Lighthouse/Program.NetCore.cs b/src/Lighthouse/Program.NetCore.cs deleted file mode 100644 index 59a4dd93..00000000 --- a/src/Lighthouse/Program.NetCore.cs +++ /dev/null @@ -1,24 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (C) 2015 - 2019 Petabridge, LLC -// -// ----------------------------------------------------------------------- - -using System; - -namespace Lighthouse -{ - public partial class Program - { -#if CORECLR - public static void Main(string[] args) - { - var lighthouseService = new LighthouseService(); - lighthouseService.Start(); - Console.WriteLine("Press Control + C to terminate."); - Console.CancelKeyPress += async (sender, eventArgs) => { await lighthouseService.StopAsync(); }; - lighthouseService.TerminationHandle.Wait(); - } -#endif - } -} \ No newline at end of file diff --git a/src/Lighthouse/Program.NetFramework.cs b/src/Lighthouse/Program.NetFramework.cs deleted file mode 100644 index 4da4f98c..00000000 --- a/src/Lighthouse/Program.NetFramework.cs +++ /dev/null @@ -1,42 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (C) 2015 - 2019 Petabridge, LLC -// -// ----------------------------------------------------------------------- - -#if !CORECLR -using Topshelf; -#endif - -namespace Lighthouse -{ - public partial class Program - { -#if !CORECLR - public static void Main(string[] args) - { - HostFactory.Run(x => - { - x.SetServiceName("Lighthouse"); - x.SetDisplayName("Lighthouse"); - x.SetDescription("Seed node for the Akka Cluster"); - - x.UseAssemblyInfoForServiceInfo(); - x.RunAsLocalSystem(); - x.StartAutomatically(); - - x.Service(sc => - { - sc.ConstructUsing(() => new LighthouseService()); - - // the start and stop methods for the service - sc.WhenStarted(s => s.Start()); - sc.WhenStopped(s => s.StopAsync().Wait()); - }); - - x.EnableServiceRecovery(r => r.RestartService(1)); - }); - } -#endif - } -} \ No newline at end of file diff --git a/src/Lighthouse/Program.cs b/src/Lighthouse/Program.cs new file mode 100644 index 00000000..0d35cb06 --- /dev/null +++ b/src/Lighthouse/Program.cs @@ -0,0 +1,42 @@ +// ----------------------------------------------------------------------- +// +// Copyright (C) 2015 - 2019 Petabridge, LLC +// +// ----------------------------------------------------------------------- + +using System; +using System.Threading.Tasks; +using Akka.Hosting; +using Microsoft.Extensions.Hosting; +using Petabridge.Cmd.Cluster; +using Petabridge.Cmd.Host; +using Petabridge.Cmd.Remote; + +namespace Lighthouse +{ + public class Program + { + public static async Task Main(string[] args) + { + var (config, actorSystemName) = LighthouseConfigurator.LaunchLighthouse(); + var hostBuilder = new HostBuilder(); + hostBuilder.ConfigureServices(services => + { + services.AddAkka(actorSystemName, builder => + { + builder.AddHocon(config) // clustering / remoting automatically configured here + .StartActors((system, registry) => + { + var pbm = PetabridgeCmd.Get(system); + pbm.RegisterCommandPalette(ClusterCommands.Instance); // enable Akka.Cluster management commands + pbm.RegisterCommandPalette(RemoteCommands.Instance); // enable Akka.Remote management commands + pbm.Start(); + }); + }); + }); + + var host = hostBuilder.Build(); + await host.RunAsync(); + } + } +} \ No newline at end of file diff --git a/src/Lighthouse/akka.hocon b/src/Lighthouse/akka.hocon index 68eb4a39..7b9a2b87 100644 --- a/src/Lighthouse/akka.hocon +++ b/src/Lighthouse/akka.hocon @@ -15,10 +15,48 @@ petabridge.cmd{ akka { actor { provider = cluster + + default-dispatcher = { + executor = channel-executor + fork-join-executor { #channelexecutor will re-use these settings + parallelism-min = 2 + parallelism-factor = 1 + parallelism-max = 64 + } + } + + internal-dispatcher = { + executor = channel-executor + throughput = 5 + fork-join-executor { + parallelism-min = 4 + parallelism-factor = 1.0 + parallelism-max = 64 + } + } } remote { log-remote-lifecycle-events = DEBUG + + default-remote-dispatcher { + type = Dispatcher + executor = channel-executor + fork-join-executor { + parallelism-min = 2 + parallelism-factor = 0.5 + parallelism-max = 16 + } + } + + backoff-remote-dispatcher { + executor = channel-executor + fork-join-executor { + parallelism-min = 2 + parallelism-max = 2 + } + } + dot-netty.tcp { transport-class = "Akka.Remote.Transport.DotNetty.TcpTransport, Akka.Remote" applied-adapters = [] diff --git a/src/common.props b/src/common.props index b5e398b2..063c0b2b 100644 --- a/src/common.props +++ b/src/common.props @@ -1,10 +1,9 @@ - Copyright © 2015-2021 Petabridge, LLC + Copyright © 2015-2022 Petabridge, LLC Petabridge - 1.5.3 - Upgraded to [Akka.NET v1.4.19](https://github.com/akkadotnet/akka.net/releases/tag/1.4.19) -Upgraded to [Petabridge.Cmd v0.8.5](https://cmd.petabridge.com/articles/RELEASE_NOTES.html#085-may-03-2021) + 1.5.5 + Upgrade [Akka.Bootstrap.Docker to 0.5.3](https://github.com/petabridge/akkadotnet-bootstrap/releases/tag/0.5.3) https://petabridge.com/images/logo.png https://github.com/petabridge/lighthouse @@ -16,13 +15,13 @@ Upgraded to [Petabridge.Cmd v0.8.5](https://cmd.petabridge.com/articles/RELEASE_ 2.4.1 - 16.10.0 - 5.10.3 + 17.1.0 + 6.6.0 netcoreapp3.1 netstandard1.6 net461 - net461 - 1.4.21 + netcoreapp3.1 + 1.4.37 0.8.5 - + \ No newline at end of file