Example #1
0
        public async Task GetSentinelMasterConnectionWriteReadFailover()
        {
            Log("Conn:");
            foreach (var server in Conn.GetServerSnapshot().ToArray())
            {
                Log("  Endpoint: " + server.EndPoint);
            }
            Log("Conn Slaves:");
            foreach (var slaves in SentinelServerA.SentinelSlaves(ServiceName))
            {
                foreach (var pair in slaves)
                {
                    Log("  {0}: {1}", pair.Key, pair.Value);
                }
            }

            var conn = Conn.GetSentinelMasterConnection(ServiceOptions);
            var s    = conn.currentSentinelMasterEndPoint.ToString();

            Log("Sentinel Master Endpoint: " + s);
            foreach (var server in conn.GetServerSnapshot().ToArray())
            {
                Log("  Server: " + server.EndPoint);
                Log("    Master Endpoint: " + server.MasterEndPoint);
                Log("    IsSlave: " + server.IsSlave);
                Log("    SlaveReadOnly: " + server.SlaveReadOnly);
                var info = conn.GetServer(server.EndPoint).Info("Replication");
                foreach (var section in info)
                {
                    Log("    Section: " + section.Key);
                    foreach (var pair in section)
                    {
                        Log("        " + pair.Key + ": " + pair.Value);
                    }
                }
            }

            IDatabase db       = conn.GetDatabase();
            var       expected = DateTime.Now.Ticks.ToString();

            Log("Tick Key: " + expected);
            var key = Me();

            db.KeyDelete(key, CommandFlags.FireAndForget);
            db.StringSet(key, expected);

            await UntilCondition(TimeSpan.FromSeconds(10),
                                 () => SentinelServerA.SentinelMaster(ServiceName).ToDictionary()["num-slaves"] != "0"
                                 );

            Log("Conditions met");

            try
            {
                Log("Failover attempted initiated");
                SentinelServerA.SentinelFailover(ServiceName);
                Log("  Success!");
            }
            catch (RedisServerException ex) when(ex.Message.Contains("NOGOODSLAVE"))
            {
                // Retry once
                Log("  Retry initiated");
                await Task.Delay(1000).ForAwait();

                SentinelServerA.SentinelFailover(ServiceName);
                Log("  Retry complete");
            }
            Log("Delaying for failover conditions...");
            await Task.Delay(2000).ForAwait();

            Log("Conditons check...");
            // Spin until complete (with a timeout) - since this can vary
            await UntilCondition(TimeSpan.FromSeconds(20), () =>
            {
                var checkConn = Conn.GetSentinelMasterConnection(ServiceOptions);
                return(s != checkConn.currentSentinelMasterEndPoint.ToString() &&
                       expected == checkConn.GetDatabase().StringGet(key));
            });

            Log("  Conditions met.");

            var conn1 = Conn.GetSentinelMasterConnection(ServiceOptions);
            var s1    = conn1.currentSentinelMasterEndPoint.ToString();

            Log("New master endpoint: " + s1);

            var actual = conn1.GetDatabase().StringGet(key);

            Log("Fetched tick key: " + actual);

            Assert.NotNull(s);
            Assert.NotNull(s1);
            Assert.NotEmpty(s);
            Assert.NotEmpty(s1);
            Assert.NotEqual(s, s1);
            // TODO: Track this down on the test race
            //Assert.Equal(expected, actual);
        }