Skip to content

Instantly share code, notes, and snippets.

@trbngr
Last active September 25, 2016 00:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trbngr/34a3a5ff0246538c4d32af989f6aa91a to your computer and use it in GitHub Desktop.
Save trbngr/34a3a5ff0246538c4d32af989f6aa91a to your computer and use it in GitHub Desktop.
Custom configs for Akka.net
private static ActorSystem CreateActorSystem(string systemName)
{
var config = ConfigurationFactory.Load()
.WithFallback(CustomConfig.Create(systemName))
.WithFallback(ClusterSingletonManager.DefaultConfig())
.WithFallback(RedisPersistence.DefaultConfig());
var path = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "akka.generated.conf"));
File.WriteAllText(path, config.ToString(true));
return ActorSystem.Create(systemName, config);
}
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using Akka.Configuration;
using EventDay.Configuration;
using Microsoft.WindowsAzure.ServiceRuntime;
namespace BackendService
{
public interface IConfigSource
{
string[] Seeds { get; }
string RedisConnectionString { get; }
string PublicHost { get; }
string PrivateHost { get; }
int Port { get; }
}
public class LocalConfigSource : IConfigSource
{
public string[] Seeds => new[] {"localhost:2551"};
public string RedisConnectionString => "127.0.0.1:6379";
public string PublicHost => "localhost";
public string PrivateHost => "localhost";
public int Port => 2551;
}
public class CloudConfigSource : IConfigSource
{
private readonly RedisConnectionElement _redisElement;
private readonly RoleInstanceEndpoint _endpoint;
public CloudConfigSource()
{
_redisElement = EventDaySection.Instance.Services.Redis;
_endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Akka"];
}
public string[] Seeds => new[]
{
"23.96.181.179:2551",
"23.96.246.27:2551"
};
public string RedisConnectionString => $"{_redisElement.Host}:{_redisElement.Port},ssl=true,password={_redisElement.Password}";
public string PublicHost => _endpoint.IPEndpoint.Address.ToString();
public string PrivateHost => Dns.GetHostEntry(Dns.GetHostName()).AddressList.First(x => x.AddressFamily == AddressFamily.InterNetwork).ToString();
public int Port => _endpoint.IPEndpoint.Port;
}
public static class CustomConfig
{
public static Config Create(string systemName)
{
#if DEBUG
var source = new LocalConfigSource();
#else
var source = new CloudConfigSource();
#endif
return Create(systemName, source);
}
public static Config Create(string systemName, IConfigSource source)
{
Console.Out.WriteLine($"seeds: {string.Join(",", source.Seeds)}");
Console.Out.WriteLine($"redis: {source.RedisConnectionString}");
Console.Out.WriteLine($"public host: {source.PublicHost}");
Console.Out.WriteLine($"private host: {source.PrivateHost}");
return $@"akka : {{
cluster : {{
seed-nodes : [{string.Join(",", source.Seeds.Select(x => $@"""akka.tcp://{systemName}@{x}"""))}]
}}
persistence : {{
journal {{
redis {{
configuration-string : ""{source.RedisConnectionString}""
}}
}}
snapshot-store {{
redis {{
configuration-string : ""{source.RedisConnectionString}""
}}
}}
}}
remote {{
helios.tcp : {{
hostname : ""{source.PrivateHost}""
public-hostname: ""{source.PublicHost}""
port: {source.Port}
}}
}}
}}";
}
}
}
using System;
using Akka.Configuration;
using FluentAssertions;
using NUnit.Framework;
namespace BackendService.Tests
{
[TestFixture]
public class CustomConfigSpecs
{
private const string Config = @"
akka {
remote {
helios.tcp {
port = 2551
}
}
cluster {
}
persistence {
journal {
plugin = ""akka.persistence.journal.redis""
redis {
class = ""Akka.Persistence.Redis.Journal.RedisJournal, Akka.Persistence.Redis""
plugin-dispatcher = ""akka.actor.default-dispatcher""
key-prefix = ""akka:persistence:journal""
}
}
snapshot-store {
plugin = ""akka.persistence.snapshot-store.redis""
redis {
class = ""Akka.Persistence.Redis.Snapshot.RedisSnapshotStore, Akka.Persistence.Redis""
plugin-dispatcher = ""akka.actor.default-dispatcher""
key-prefix = ""akka:persistence:snapshots""
}
}
}
}
";
[Test]
public void CloudConfigIsParsedCorrectly()
{
AssertConfigSource(new CloudConfigSource());
}
[Test]
public void LocalConfigIsParsedCorrectly()
{
AssertConfigSource(new LocalConfigSource());
}
[Test]
public void CustomConfigIsParsedCorrectly()
{
AssertConfigSource(new ConfigSource(new[] { "one", "two" }, "redishost:1234", "public", "private"));
}
public void AssertConfigSource(IConfigSource source)
{
var config = ConfigurationFactory.ParseString(Config)
.WithFallback(CustomConfig.Create("tests", source));
Console.Out.WriteLine(config.ToString(includeFallback: true));
var journalConfig = config.GetString("akka.persistence.journal.redis.configuration-string");
journalConfig.Should().Be(source.RedisConnectionString);
var snapshotStoreConfig = config.GetString("akka.persistence.snapshot-store.redis.configuration-string");
snapshotStoreConfig.Should().Be(source.RedisConnectionString);
config.GetInt("akka.remote.helios.tcp.port").Should().Be(source.Port);
config.GetString("akka.remote.helios.tcp.hostname").Should().Be(source.PrivateHost);
config.GetString("akka.remote.helios.tcp.public-hostname").Should().Be(source.PublicHost);
var cluster = config.GetConfig("akka.cluster");
var seeds = cluster.GetStringList("seed-nodes");
seeds.Should().HaveCount(source.Seeds.Length);
seeds.Should().BeEquivalentTo(source.Seeds);
}
class ConfigSource : IConfigSource
{
public ConfigSource(string[] seeds, string redisConnectionString, string publicHost, string privateHost)
{
Seeds = seeds;
RedisConnectionString = redisConnectionString;
PublicHost = publicHost;
PrivateHost = privateHost;
}
public string[] Seeds { get; }
public string RedisConnectionString { get; }
public string PublicHost { get; }
public string PrivateHost { get; }
public int Port => 2551;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment