forked from akkadotnet/akka.net
/
StartupWithOneThreadSpec.cs
88 lines (79 loc) · 3.8 KB
/
StartupWithOneThreadSpec.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//-----------------------------------------------------------------------
// <copyright file="StartupWithOneThreadSpec.cs" company="Akka.NET Project">
// Copyright (C) 2009-2021 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2021 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.Threading;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Actor.Dsl;
using Akka.Configuration;
using Akka.Event;
using Akka.TestKit;
using Akka.Util;
using Xunit;
using Xunit.Abstractions;
namespace Akka.Cluster.Tests
{
public class StartupWithOneThreadSpec : AkkaSpec
{
private static readonly Config Configuration = ConfigurationFactory.ParseString(@"
akka.actor.creation-timeout = 10s
akka.actor.default-dispatcher.Type = ForkJoinDispatcher
akka.actor.default-dispatcher.dedicated-thread-pool.thread-count = 1
akka.actor.provider = ""Akka.Cluster.ClusterActorRefProvider, Akka.Cluster""
akka.remote.dot-netty.tcp.port = 0
akka.cluster.downing-provider-class = ""Akka.Cluster.SBR.SplitBrainResolverProvider, Akka.Cluster""
akka.cluster.split-brain-resolver.active-strategy = keep-majority
");
private long _startTime;
public StartupWithOneThreadSpec(ITestOutputHelper output) : base(Configuration, output) {
_startTime = MonotonicClock.GetTicks();
}
private Props TestProps
{
get
{
Action<IActorDsl> actor = (c =>
{
c.ReceiveAny((o, context) => context.Sender.Tell(o));
c.OnPreStart = context =>
{
var log = context.GetLogger();
var cluster = Cluster.Get(context.System);
log.Debug("Started {0} {1}", cluster.SelfAddress, Thread.CurrentThread.Name);
};
});
return Props.Create(() => new Act(actor));
}
}
[Fact]
public async Task A_cluster_must_startup_with_one_dispatcher_thread()
{
// This test failed before fixing https://github.com/akkadotnet/akka.net/issues/1959 when adding a sleep before the
// Await of GetClusterCoreRef in the Cluster extension constructor.
// The reason was that other cluster actors were started too early and
// they also tried to get the Cluster extension and thereby blocking
// dispatcher threads.
// Note that the Cluster extension is started via ClusterActorRefProvider
// before ActorSystem.apply returns, i.e. in the constructor of AkkaSpec.
var totalStartupTime = TimeSpan.FromTicks(MonotonicClock.GetTicks() - _startTime).TotalMilliseconds;
Assert.True(totalStartupTime < (Sys.Settings.CreationTimeout - TimeSpan.FromSeconds(2)).TotalMilliseconds);
Sys.ActorOf(TestProps).Tell("hello");
Sys.ActorOf(TestProps).Tell("hello");
Sys.ActorOf(TestProps).Tell("hello");
var cluster = Cluster.Get(Sys);
totalStartupTime = TimeSpan.FromTicks(MonotonicClock.GetTicks() - _startTime).TotalMilliseconds;
Assert.True(totalStartupTime < (Sys.Settings.CreationTimeout - TimeSpan.FromSeconds(2)).TotalMilliseconds);
ExpectMsg("hello");
ExpectMsg("hello");
ExpectMsg("hello");
// perform a self-join
var cts = new CancellationTokenSource(TimeSpan.FromSeconds((3)));
var selfAddress = cluster.SelfAddress;
await cluster.JoinSeedNodesAsync(new[] { selfAddress }, cts.Token);
}
}
}