Skip to content

Commit 22e3e9f

Browse files
Add Lighthouse.NetCoreApp for .NET Core compatible seed node (#37) (#38)
* Upgrade to Akka v1.3.0 (#36) * apply petabridge dotnet new * build working on net45 * build working on net45 * apply petabridge dotnet new * upgrade to akka v1.3.0 * lighthouse.netcoreapp * readme
1 parent ef55d07 commit 22e3e9f

9 files changed

+288
-25
lines changed

Lighthouse.sln

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{183986D1
1515
build.sh = build.sh
1616
EndProjectSection
1717
EndProject
18+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lighthouse.NetCoreApp", "src\Lighthouse.NetCoreApp\Lighthouse.NetCoreApp.csproj", "{68DA756A-9D3D-4C7E-AA07-8741D2DE0B95}"
19+
EndProject
1820
Global
1921
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2022
Debug|Any CPU = Debug|Any CPU
@@ -29,6 +31,10 @@ Global
2931
{0F9B9BC6-9F86-40E8-BA9B-D27BF3AC7970}.Debug|Any CPU.Build.0 = Debug|Any CPU
3032
{0F9B9BC6-9F86-40E8-BA9B-D27BF3AC7970}.Release|Any CPU.ActiveCfg = Release|Any CPU
3133
{0F9B9BC6-9F86-40E8-BA9B-D27BF3AC7970}.Release|Any CPU.Build.0 = Release|Any CPU
34+
{68DA756A-9D3D-4C7E-AA07-8741D2DE0B95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35+
{68DA756A-9D3D-4C7E-AA07-8741D2DE0B95}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{68DA756A-9D3D-4C7E-AA07-8741D2DE0B95}.Release|Any CPU.ActiveCfg = Release|Any CPU
37+
{68DA756A-9D3D-4C7E-AA07-8741D2DE0B95}.Release|Any CPU.Build.0 = Release|Any CPU
3238
EndGlobalSection
3339
GlobalSection(SolutionProperties) = preSolution
3440
HideSolutionNode = FALSE

README.md

+39-22
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,60 @@
11
# Lighthouse
22

3-
Update this readme file with your details.
3+
**Lighthouse** is a simple service-discovery tool for Akka.Cluster, designed to make it easier to place nice with PaaS deployments like Azure / Elastic Beanstalk / AppHarbor.
44

5-
## Building this solution
6-
To run the build script associated with this solution, execute the following:
5+
## Running on .NET 4.5
6+
7+
Lighthouse runs on [Akka.NET](https://github.com/akkadotnet/akka.net) version 1.3.1, which supports .NET 4.5 and .NET Core 1.1/.NET Standard 1.6. To package the executable and run the .NET 4.5 version locally, clone this repo and build the `Lighthouse` project. Running Lighthouse.exe in a console should produce an output similar to this:
78

8-
**Windows**
99
```
10-
c:\> build.cmd all
10+
Topshelf.HostFactory: Configuration Result:
11+
[Success] Name Lighthouse
12+
[Success] DisplayName Lighthouse Service Discovery
13+
[Success] Description Lighthouse Service Discovery for Akka.NET Clusters
14+
[Success] ServiceName Lighthouse
15+
Topshelf.HostConfigurators.HostConfiguratorImpl: Topshelf v3.2.150.0, .NET Framework v4.0.30319.42000
1116
```
1217

13-
**Linux / OS X**
18+
The Lighthouse .NET 4.5 project is built as a [Topshelf](https://github.com/Topshelf/Topshelf) service. This allows you to install Lighthouse as a Windows Service using a command like this:
19+
1420
```
15-
c:\> build.sh all
21+
Lighthouse.exe install --localsystem --autostart
1622
```
1723

18-
If you need any information on the supported commands, please execute the `build.[cmd|sh] help` command.
24+
See the Topshelf documentation for more info on command line arguments for installing a Topshelf service.
25+
26+
# Running on .NET Core
1927

20-
This build script is powered by [FAKE](https://fake.build/); please see their API documentation should you need to make any changes to the [`build.fsx`](build.fsx) file.
28+
Lighthouse also includes a .NET Core-compatible version under a separate project named `Lighthouse.NetCoreApp`. This project does not build as a Topshelf web service. You have 2 ways that you can run this version:
2129

22-
### Conventions
23-
The attached build script will automatically do the following based on the conventions of the project names added to this project:
30+
- using the .NET CLI
31+
- building the project as a standalone .exe for your specific [runtime identifier](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog)
2432

25-
* Any project name ending with `.Tests` will automatically be treated as a [XUnit2](https://xunit.github.io/) project and will be included during the test stages of this build script;
26-
* Any project name ending with `.Tests` will automatically be treated as a [NBench](https://github.com/petabridge/NBench) project and will be included during the test stages of this build script; and
27-
* Any project meeting neither of these conventions will be treated as a NuGet packaging target and its `.nupkg` file will automatically be placed in the `bin\nuget` folder upon running the `build.[cmd|sh] all` command.
33+
#### Using the .NET CLI
2834

29-
### DocFx for Documentation
30-
This solution also supports [DocFx](http://dotnet.github.io/docfx/) for generating both API documentation and articles to describe the behavior, output, and usages of your project.
35+
Build the project either in Visual Studio 2017 or using `dotnet build -c Release Lighthouse.NetCoreApp.csproj`. This will output `Lighthouse.NetCoreApp.dll` in your `bin/Release` folder. From there, running `dotnet ./Lighthouse.NetCoreApp.dll` will start Lighthouse. Pressing `Enter` will exit.
3136

32-
All of the relevant articles you wish to write should be added to the `/docs/articles/` folder and any API documentation you might need will also appear there.
37+
#### Building the project as an .exe
3338

34-
All of the documentation will be statically generated and the output will be placed in the `/docs/_site/` folder.
39+
You need to restore the dependencies for the target runtime identifier that you want to build the executable for:
3540

36-
### Release Notes, Version Numbers, Etc
37-
This project will automatically populate its release notes in all of its modules via the entries written inside [`RELEASE_NOTES.md`](RELEASE_NOTES.md) and will automatically update the versions of all assemblies and NuGet packages via the metadata included inside [`common.props`](src/common.props).
41+
```
42+
dotnet restore -r win7-x64
43+
```
44+
45+
Then, you may publish the executable using the command:
46+
47+
```
48+
dotnet publish -c Release -r win7-x64 -f netcoreapp1.1
49+
```
3850

39-
If you add any new projects to the solution created with this template, be sure to add the following line to each one of them in order to ensure that you can take advantage of `common.props` for standardization purposes:
51+
This will include a `publish` folder in your bin directory that will include the .exe and the .NET Core runtime dependencies:
4052

4153
```
42-
<Import Project="..\common.props" />
54+
bin/
55+
Release/
56+
netcoreapp1.1/
57+
win7-x64/
58+
publish/
59+
Lighthouse.NetCoreApp.exe
4360
```

src/Lighthouse.NetCoreApp/App.config

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<configSections>
4+
<section name="akka" type="Akka.Configuration.Hocon.AkkaConfigurationSection, Akka" />
5+
</configSections>
6+
<akka>
7+
<hocon>
8+
<![CDATA[
9+
lighthouse{
10+
actorsystem: "webcrawler" #POPULATE NAME OF YOUR ACTOR SYSTEM HERE
11+
}
12+
13+
akka {
14+
actor {
15+
provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
16+
}
17+
18+
remote {
19+
log-remote-lifecycle-events = DEBUG
20+
dot-netty.tcp {
21+
transport-class = "Akka.Remote.Transport.DotNetty.TcpTransport, Akka.Remote"
22+
applied-adapters = []
23+
transport-protocol = tcp
24+
#will be populated with a dynamic host-name at runtime if left uncommented
25+
#public-hostname = "POPULATE STATIC IP HERE"
26+
hostname = "0.0.0.0"
27+
port = 4053
28+
}
29+
}
30+
31+
loggers = ["Akka.Logger.NLog.NLogLogger, Akka.Logger.NLog"]
32+
33+
cluster {
34+
#will inject this node as a self-seed node at run-time
35+
seed-nodes = [] #manually populate other seed nodes here, i.e. "akka.tcp://[email protected]:4053", "akka.tcp://[email protected]:4044"
36+
roles = [lighthouse]
37+
}
38+
}
39+
]]>
40+
</hocon>
41+
</akka>
42+
</configuration>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp1.1</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Akka" Version="1.3.1" />
10+
<PackageReference Include="Akka.Cluster" Version="1.3.1" />
11+
<PackageReference Include="Akka.Logger.NLog" Version="1.3.0-beta" />
12+
<PackageReference Include="Akka.Remote" Version="1.3.1" />
13+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.2" />
14+
<PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="1.1.2" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<None Update="App.config">
19+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
20+
</None>
21+
<None Update="NLog.config">
22+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
23+
</None>
24+
</ItemGroup>
25+
26+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright 2014-2015 Aaron Stannard, Petabridge LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4+
// this file except in compliance with the License. You may obtain a copy of the
5+
// License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software distributed
10+
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
// specific language governing permissions and limitations under the License.
13+
14+
using System.Linq;
15+
using Akka.Actor;
16+
using Akka.Configuration;
17+
using ConfigurationException = Akka.Configuration.ConfigurationException;
18+
19+
namespace Lighthouse.NetCoreApp
20+
{
21+
/// <summary>
22+
/// Launcher for the Lighthouse <see cref="ActorSystem"/>
23+
/// </summary>
24+
public static class LighthouseHostFactory
25+
{
26+
public static ActorSystem LaunchLighthouse(string ipAddress = null, int? specifiedPort = null)
27+
{
28+
var systemName = "lighthouse";
29+
var clusterConfig = GetConfig();
30+
31+
var lighthouseConfig = clusterConfig.GetConfig("lighthouse");
32+
if (lighthouseConfig != null)
33+
{
34+
systemName = lighthouseConfig.GetString("actorsystem", systemName);
35+
}
36+
37+
var remoteConfig = clusterConfig.GetConfig("akka.remote");
38+
ipAddress = ipAddress ??
39+
remoteConfig.GetString("dot-netty.tcp.public-hostname") ??
40+
"127.0.0.1"; //localhost as a final default
41+
int port = specifiedPort ?? remoteConfig.GetInt("dot-netty.tcp.port");
42+
43+
if (port == 0) throw new ConfigurationException("Need to specify an explicit port for Lighthouse. Found an undefined port or a port value of 0 in App.config.");
44+
45+
var selfAddress = string.Format("akka.tcp://{0}@{1}:{2}", systemName, ipAddress, port);
46+
var seeds = clusterConfig.GetStringList("akka.cluster.seed-nodes");
47+
if (!seeds.Contains(selfAddress))
48+
{
49+
seeds.Add(selfAddress);
50+
}
51+
52+
var injectedClusterConfigString = seeds.Aggregate("akka.cluster.seed-nodes = [", (current, seed) => current + (@"""" + seed + @""", "));
53+
injectedClusterConfigString += "]";
54+
55+
var finalConfig = ConfigurationFactory.ParseString(
56+
string.Format(@"akka.remote.dot-netty.tcp.public-hostname = {0}
57+
akka.remote.dot-netty.tcp.port = {1}", ipAddress, port))
58+
.WithFallback(ConfigurationFactory.ParseString(injectedClusterConfigString))
59+
.WithFallback(clusterConfig);
60+
61+
return ActorSystem.Create(systemName, finalConfig);
62+
}
63+
64+
private static Config GetConfig()
65+
{
66+
var configString = @"
67+
lighthouse{
68+
actorsystem: ""webcrawler"" #POPULATE NAME OF YOUR ACTOR SYSTEM HERE
69+
}
70+
71+
akka {
72+
actor {
73+
provider = ""Akka.Cluster.ClusterActorRefProvider, Akka.Cluster""
74+
}
75+
76+
remote {
77+
log-remote-lifecycle-events = DEBUG
78+
dot-netty.tcp {
79+
transport-class = ""Akka.Remote.Transport.DotNetty.TcpTransport, Akka.Remote""
80+
applied-adapters = []
81+
transport-protocol = tcp
82+
#will be populated with a dynamic host-name at runtime if left uncommented
83+
#public-hostname = ""POPULATE STATIC IP HERE""
84+
hostname = ""0.0.0.0""
85+
port = 4053
86+
}
87+
}
88+
89+
cluster {
90+
#will inject this node as a self-seed node at run-time
91+
seed-nodes = [] #manually populate other seed nodes here, i.e. ""akka.tcp://[email protected]:4053"", ""akka.tcp://[email protected]:4044""
92+
roles = [lighthouse]
93+
}
94+
}
95+
";
96+
return ConfigurationFactory.ParseString(configString);
97+
}
98+
}
99+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2014-2015 Aaron Stannard, Petabridge LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4+
// this file except in compliance with the License. You may obtain a copy of the
5+
// License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software distributed
10+
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
// specific language governing permissions and limitations under the License.
13+
14+
using System.Threading.Tasks;
15+
using Akka.Actor;
16+
17+
namespace Lighthouse.NetCoreApp
18+
{
19+
public class LighthouseService
20+
{
21+
private readonly string _ipAddress;
22+
private readonly int? _port;
23+
24+
private ActorSystem _lighthouseSystem;
25+
26+
public LighthouseService() : this(null, null) { }
27+
28+
public LighthouseService(string ipAddress, int? port)
29+
{
30+
_ipAddress = ipAddress;
31+
_port = port;
32+
}
33+
34+
public void Start()
35+
{
36+
_lighthouseSystem = LighthouseHostFactory.LaunchLighthouse(_ipAddress, _port);
37+
}
38+
39+
public async Task StopAsync()
40+
{
41+
await _lighthouseSystem.Terminate();
42+
}
43+
}
44+
}

src/Lighthouse.NetCoreApp/NLog.config

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" ?>
2+
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4+
<targets>
5+
<target name="eventlog" xsi:type="EventLog" layout="${logger}: ${message} ${exception:format=tostring}" source="Lighthouse" log="Application" />
6+
<target name="console" xsi:type="ColoredConsole" layout="${logger}: ${message} ${exception:format=tostring}"></target>
7+
</targets>
8+
9+
<rules>
10+
<logger name="*" minlevel="Warn" writeTo="eventlog" />
11+
<logger name="*" minlevel="Info" writeTo="console" />
12+
</rules>
13+
</nlog>

src/Lighthouse.NetCoreApp/Program.cs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace Lighthouse.NetCoreApp
5+
{
6+
class Program
7+
{
8+
static void Main(string[] args)
9+
{
10+
var lighthouseService = new LighthouseService();
11+
lighthouseService.Start();
12+
Console.ReadLine();
13+
lighthouseService.StopAsync().Wait();
14+
}
15+
}
16+
}

src/Lighthouse/Lighthouse.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="Akka" Version="1.3.0" />
11-
<PackageReference Include="Akka.Cluster" Version="1.3.0" />
10+
<PackageReference Include="Akka" Version="1.3.1" />
11+
<PackageReference Include="Akka.Cluster" Version="1.3.1" />
1212
<PackageReference Include="Akka.Logger.NLog" Version="1.3.0-beta" />
13-
<PackageReference Include="Akka.Remote" Version="1.3.0" />
13+
<PackageReference Include="Akka.Remote" Version="1.3.1" />
1414
<PackageReference Include="Topshelf" Version="3.2.0" />
1515
<PackageReference Include="Topshelf.NLog" Version="3.2.0" />
1616
</ItemGroup>

0 commit comments

Comments
 (0)