示例#1
0
        public void Follower_as_a_single_node_becomes_leader_automatically()
        {
            var hub = new InMemoryTransportHub();
            var storageEnvironmentOptions = StorageEnvironmentOptions.CreateMemoryOnly();

            storageEnvironmentOptions.OwnsPagers = false;

            var raftEngineOptions = new RaftEngineOptions(
                new NodeConnectionInfo {
                Name = "node1"
            },
                storageEnvironmentOptions,
                hub.CreateTransportFor("node1"),
                new DictionaryStateMachine()
                )
            {
                ElectionTimeout  = 1000,
                HeartbeatTimeout = 1000 / 6
            };

            PersistentState.ClusterBootstrap(raftEngineOptions);
            storageEnvironmentOptions.OwnsPagers = true;

            using (var raftNode = new RaftEngine(raftEngineOptions))
            {
                Assert.Equal(RaftEngineState.Leader, raftNode.State);
            }
        }
示例#2
0
文件: Program.cs 项目: ppekrol/Rachis
        private static void Main(string[] args)
        {
            var options = new TailFeatherCommandLineOptions();

            if (Parser.Default.ParseArguments(args, options) == false)
            {
                var autoBuild = HelpText.AutoBuild(options);
                HelpText.DefaultParsingErrorsHandler(options, autoBuild);
                Console.WriteLine(autoBuild.ToString());
                return;
            }

            var nodeName = options.NodeName ?? (Environment.MachineName + ":" + options.Port);

            Console.Title = string.Format("Node name: {0}, port: {1}", nodeName, options.Port);

            var kvso = StorageEnvironmentOptions.ForPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, options.DataPath, "KeyValue"));

            using (var statemachine = new KeyValueStateMachine(kvso))
            {
                var storageEnvironmentOptions = StorageEnvironmentOptions.ForPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, options.DataPath, "Raft"));
                var httpTransport             = new HttpTransport(nodeName);
                var raftEngineOptions         = new RaftEngineOptions(
                    new NodeConnectionInfo
                {
                    Name = nodeName,
                    Uri  = new Uri("http://" + Environment.MachineName + ":" + options.Port),
                },
                    storageEnvironmentOptions,
                    httpTransport,
                    statemachine
                    )
                {
                    ElectionTimeout              = 5 * 1000,
                    HeartbeatTimeout             = 1000,
                    MaxLogLengthBeforeCompaction = 25
                };

                if (options.Boostrap)
                {
                    PersistentState.ClusterBootstrap(raftEngineOptions);
                    Console.WriteLine("Setup node as the cluster seed, exiting...");
                    return;
                }

                using (var raftEngine = new RaftEngine(raftEngineOptions))
                {
                    using (WebApp.Start(new StartOptions
                    {
                        Urls = { "http://+:" + options.Port + "/" }
                    }, builder =>
                    {
                        var httpConfiguration = new HttpConfiguration();
                        httpConfiguration.Formatters.Remove(httpConfiguration.Formatters.XmlFormatter);
                        httpConfiguration.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
                        httpConfiguration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
                        RaftWebApiConfig.Load();
                        httpConfiguration.MapHttpAttributeRoutes();
                        httpConfiguration.Properties[typeof(HttpTransportBus)] = httpTransport.Bus;
                        httpConfiguration.Properties[typeof(RaftEngine)] = raftEngine;
                        builder.UseWebApi(httpConfiguration);
                    }))
                    {
                        Console.WriteLine("Ready @ http://" + Environment.MachineName + ":" + options.Port + "/, press ENTER to stop");

                        Console.ReadLine();
                    }
                }
            }
        }
示例#3
0
        protected RaftEngine CreateNetworkAndGetLeader(int nodeCount, int messageTimeout = -1)
        {
            var leaderIndex = new Random().Next(0, nodeCount);

            if (messageTimeout == -1)
            {
                messageTimeout = Debugger.IsAttached ? 3 * 1000 : 500;
            }
            var nodeNames = new string[nodeCount];

            for (int i = 0; i < nodeCount; i++)
            {
                nodeNames[i] = "node" + i;
            }

            WriteLine("{0} selected as seed", nodeNames[leaderIndex]);
            var allNodesFinishedJoining = new ManualResetEventSlim();

            for (int index = 0; index < nodeNames.Length; index++)
            {
                var nodeName = nodeNames[index];
                var storageEnvironmentOptions = StorageEnvironmentOptions.CreateMemoryOnly();
                storageEnvironmentOptions.OwnsPagers = false;
                var options = CreateNodeOptions(nodeName, messageTimeout, storageEnvironmentOptions, nodeNames);
                if (leaderIndex == index)
                {
                    PersistentState.ClusterBootstrap(options);
                }
                storageEnvironmentOptions.OwnsPagers = true;
                var engine = new RaftEngine(options);
                _nodes.Add(engine);
                if (leaderIndex == index)
                {
                    engine.TopologyChanged += command =>
                    {
                        if (command.Requested.AllNodeNames.All(command.Requested.IsVoter))
                        {
                            allNodesFinishedJoining.Set();
                        }
                    };
                    for (int i = 0; i < nodeNames.Length; i++)
                    {
                        if (i == leaderIndex)
                        {
                            continue;
                        }
                        Assert.True(engine.AddToClusterAsync(new NodeConnectionInfo {
                            Name = nodeNames[i]
                        }).Wait(3000));
                    }
                }
            }
            if (nodeCount == 1)
            {
                allNodesFinishedJoining.Set();
            }
            Assert.True(allNodesFinishedJoining.Wait(5000 * nodeCount));

            var raftEngine = _nodes[leaderIndex];


            var transport = (InMemoryTransportHub.InMemoryTransport)_inMemoryTransportHub.CreateTransportFor(raftEngine.Name);

            transport.ForceTimeout();
            Assert.True(_nodes[leaderIndex].WaitForLeader());
            var leader = _nodes.FirstOrDefault(x => x.State == RaftEngineState.Leader);

            Assert.NotNull(leader);

            return(_nodes[leaderIndex]);
        }