Inheritance: ISortedSetCommands
 public void Setup()
 {
     var connection = new RedisConnection("127.0.0.1", allowAdmin: true);
     connection.Open();
     connection.Server.FlushDb(0);
     connection.Close(false);
 }
        internal async Task<long> PerformBitOperation(
            RedisConnection connection)
        {
            var keys = new[] { LeftKey, RightKey };

            if ("AND".Equals(Operation, StringComparison.Ordinal))
            {
                return await connection.Strings.BitwiseAnd(Db, Key, keys);
            }
            
            if ("OR".Equals(Operation, StringComparison.Ordinal))
            {
                return await connection.Strings.BitwiseOr(Db, Key, keys);
            }

            if ("XOR".Equals(Operation, StringComparison.Ordinal))
            {
                return await connection.Strings.BitwiseXOr(Db, Key, keys);
            }

            throw new InvalidOperationException(
                string.Format(
                    CultureInfo.CurrentUICulture,
                    ErrorMessages.CompositeUserActivityReport_PerformBitOperation_Unsupported,
                    Operation));
        }
        private static async Task<RedisConnection> GetRedisConnection(string host)
        {
            RedisConnection c = new RedisConnection(host);
            await c.Open();
            return c;

        }
 public RedisBooksleevePersistence()
 {
     if (conn == null)
     {
         conn = GetRedisConnection("localhost").Result;
     }
 }
示例#5
0
 public RedisSignalBus(RedisConnection redisConnection)
 {
     _handlers = new ConcurrentDictionary<string, SafeSet<EventHandler<SignaledEventArgs>>>();
     _redisConnection = redisConnection;
     _subscriberConnection = _redisConnection.GetOpenSubscriberChannel();
     _subscriberConnection.MessageReceived += OnRedisMessageReceived;
 }
示例#6
0
        public void Test()
        {
            Debug.WriteLine("Iniciando");

            using (var conn = new RedisConnection("localhost"))
            {
                conn.Open();
                conn.Strings.Set(0, "nome", "joão");
            }

            Thread.Sleep(2000);

            using (var conn = new RedisConnection("localhost", 6380))
            {
                conn.Open();
                conn.Strings.GetString(0, "nome").Result.ShouldEqual("joão");
            }

            this.redisMaster.Kill();

            Thread.Sleep(2000);

            using (var conn = new RedisConnection("localhost", 6380))
            {
                conn.Open();
                conn.Strings.GetString(0, "nome").Result.ShouldEqual("joão");

                conn.Strings.Set(0, "idade", "27");
                conn.Strings.GetString(0, "idade").Result.ShouldEqual("27");
            }

            Debug.WriteLine("Fim");
        }
示例#7
0
 public void CanNotOpenNonsenseConnection_DNS()
 {
     using (var conn = new RedisConnection("doesnot.exist.ds.aasd981230d.com", 6500))
     {
         conn.Wait(conn.Open());
     }
 }
示例#8
0
 public void CanNotOpenNonsenseConnection()
 {
     using (var conn = new RedisConnection("127.0.0.1", 6500))
     {
         conn.Wait(conn.Open());
     }
 }
示例#9
0
 public List<CanvasBrushAction> GetBrushActions(string canvasId, int currentPosition)
 {
     List<CanvasBrushAction> actions = new List<CanvasBrushAction>();
     string[] storedActions = null;
     using (var conn = new RedisConnection(_redisConfiguration.HostName, _redisConfiguration.
     Port, password: _redisConfiguration.Password))
     {
         conn.Open();
         var rangeTask = conn.Lists.RangeString(0, ACTION_PREFIX + canvasId, currentPosition,
         Int32.MaxValue);
         storedActions = rangeTask.Result;
     }
     if (storedActions != null)
     {
         foreach (string storedAction in storedActions)
         {
             actions.Add(JsonConvert.DeserializeObject<CanvasBrushAction>(storedAction));
         }
         actions.Sort(new Comparison<CanvasBrushAction>((a, b) =>
         {
             return a.Sequence.
                 CompareTo(b.Sequence);
         }));
     }
     return actions;
 }
示例#10
0
        public static int Main(string[] args)
        {
            Logger.Info("Application started.");

            AppDomain.CurrentDomain.UnhandledException += OnUnhandledApplicationException;

            // Log the exception, but do not mark it as observed. The process will be terminated and restarted
            // automatically by AppHarbor
            TaskScheduler.UnobservedTaskException +=
                (sender, e) => Logger.ErrorException("An unobserved task exception occurred", e.Exception);

            try
            {
                connection = GetOpenConnection();

                ProcessQueue(new[] { "queue:execute" });
            }
            catch (Exception ex)
            {
                Logger.ErrorException("An error occured while processing the queue.", ex);
            }

            Logger.Info("Application ending.");

            return -1; // Return a non-zero code so AppHarbor restarts the worker
        }
示例#11
0
        public RedisConnection GetOpen()
        {
            lock (syncConnection)
            {
                if (_Connection != null && !(_Connection.State == RedisConnectionBase.ConnectionState.Closed || _Connection.State == RedisConnectionBase.ConnectionState.Closing))
                {
                    return _Connection;
                }

                if (_Connection == null || (_Connection.State == RedisConnectionBase.ConnectionState.Closed || _Connection.State == RedisConnectionBase.ConnectionState.Closing))
                {
                    try
                    {
                        RoqueTrace.Source.Trace(TraceEventType.Information, "[REDIS] connecting to {0}:{1}", _Host, _Port);

                        _Connection = new RedisConnection(_Host, _Port, _Timeout);
                        var openAsync = _Connection.Open();
                        _Connection.Wait(openAsync);

                        RoqueTrace.Source.Trace(TraceEventType.Information, "[REDIS] connected");
                    }
                    catch (Exception ex)
                    {
                        RoqueTrace.Source.Trace(TraceEventType.Error, "[REDIS] error connecting to {0}:{1}, {2}", _Host, _Port, ex.Message, ex);
                        throw;
                    }
                }
                return _Connection;
            }
        }
示例#12
0
        // could also be void; only a Task here so I can Wait on
        // completion from my Main method, which is not declared
        // as async
        async static Task AsyncRedisUsage()
        {
            const int db = 4; // no reason

            using(var conn = new RedisConnection("127.0.0.1"))
            {
                // let's wait until all handshakes have happened
                await conn.Open();
                var existed = conn.Keys.Remove(db, "some-key");
                for (int i = 0; i < 100; i++)
                {   // this are also tasks, but I don't
                    // need to wait on them in this case
#pragma warning disable 4014
                    conn.Strings.Increment(db, "some-key");
#pragma warning restore 4014
                }
                // at this point, some messages are flying around
                // from a background queue, with responses being
                // handled by IOCP; let's add a GET onto the
                // bottom of the queue, and let other stuff
                // happen until we have the answer (obviously
                // we could make much more subtle use here, by
                // awaiting multiple things requested much earlier,
                // or by doing some SQL Server work etc before
                // calling await, essentially acting as a "join")
                string result = await conn.Strings.GetString(db, "some-key");
                Console.WriteLine(await existed
                    ? "(it already existed; we removed it)"
                    : "(it didn't exist)");
                Console.WriteLine(result);
            }
        }
示例#13
0
 public bool ConnectionReady()
 {
     if (_redisConnection == null || _redisConnection.State != RedisConnectionBase.ConnectionState.Open)
     {
         lock (_connectionLock)
         {
             if (_redisConnection == null || _redisConnection.State != RedisConnectionBase.ConnectionState.Open)
             {
                 _redisConnection = new RedisConnection(Host, Port, password: Password);
                 try
                 {
                     _redisConnection.Open();
                     _subscriberConnection = _redisConnection.GetOpenSubscriberChannel();
                     _subscriberConnection.MessageReceived += OnRedisMessageReceived;
                     _subscriberConnection.Error += OnRedisError;
                     return true;
                 } 
                 catch (Exception ex)
                 {
                     return false;
                 }
             }
         }
     }
     return true;
 }
示例#14
0
        private bool ConnectionReady()
        {
            if (_redisConnection == null || _redisConnection.State != RedisConnectionBase.ConnectionState.Open)
            {
                lock (_connectionLock)
                {
                    if (_redisConnection == null || _redisConnection.State != RedisConnectionBase.ConnectionState.Open)
                    {
                        _redisConnection = new RedisConnection(Host, Port, password: Password, maxUnsent: 1);

                        try
                        {
                            _redisConnection.Open().Wait();
                            return true;                
                        } 
                        catch (Exception ex)
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }
示例#15
0
 public void CanNotOpenNonsenseConnection_IP()
 {
     using (var conn = new RedisConnection(Config.LocalHost, 6500))
     {
         conn.Wait(conn.Open());
     }
 }
示例#16
0
 public static void foo()
 {
     using (var redis = new RedisConnection("goosefish.redistogo.com", 9836, -1, "88f5c87381f5564b18b4ecba2647e9ab")) {
         redis.Open();
         redis.Lists.AddLast(1, "w00t", "t00t");
     }
 }
        public void should_result_in_field5_with_6()
        {
            using (var client = new RedisConnection("localhost"))
            {
                client.Open();

                var redis = new RedisBooksleeveConnector(client);

                var key = "hello";
                var field1 = "world";
                var field2 = "world2";
                var field3 = "w3";
                var field4 = "w4";
                var field5 = "w5";
                var field6 = "w6";

                redis.HSet(key, field1, "1");
                redis.HSet(key, field2, "2");
                redis.HSet(key, field3, "3");
                redis.HSet(key, field4, "4");
                redis.HSet(key, field5, "5");
                redis.HSet(key, field6, "6");

                var result = redis.HGetAll(key);
                Assert.That(result[field5], Is.EqualTo("5"));
            }
        }
        public Task<RedisConnection> CreateRedisConnection()
        {
            var settings = RedisConnectionProvider.Instance.ConnectionsSettings;
            var redisConnection = new RedisConnection(host: settings["host"], port: Convert.ToInt32(settings["port"]), password: settings["password"]);
            var taskCreateConnection = new TaskCompletionSource<RedisConnection>();

            try
            {
                redisConnection.Open().ContinueWith((task) =>
                    {
                        if (!task.IsFaulted)
                        {
                            taskCreateConnection.SetResult(redisConnection);
                        }
                        else
                        {
                            task.Exception.Handle(x => true);
                            taskCreateConnection.SetException(task.Exception);
                        }
                    }, TaskScheduler.Default);
            }
            catch (Exception ex)
            {
                taskCreateConnection.SetException(ex);
            }

            return taskCreateConnection.Task;
        }
示例#19
0
 public void ClearData()
 {
     connection = new RedisConnection("localhost", 6379, -1, null, 2147483647, true,10000);
     subject = new RedisRepository(connection);
     connection.Open();
     connection.Server.FlushDb(db);
 }
示例#20
0
        public RedisMessageBus(string server, int port, string password, int db, IEnumerable<string> keys, IDependencyResolver resolver)
            : base(resolver)
        {
            _db = db;
            _keys = keys.ToArray();

            _connection = new RedisConnection(host: server, port: port, password: password);

            _connection.Closed += OnConnectionClosed;
            _connection.Error += OnConnectionError;

            // Start the connection
            _connectTask = _connection.Open().Then(() =>
            {
                // Create a subscription channel in redis
                _channel = _connection.GetOpenSubscriberChannel();

                // Subscribe to the registered connections
                _channel.Subscribe(_keys, OnMessage);

                // Dirty hack but it seems like subscribe returns before the actual
                // subscription is properly setup in some cases
                while (_channel.SubscriptionCount == 0)
                {
                    Thread.Sleep(500);
                }
            });
        }
示例#21
0
 private async static Task WithRedisAsync(Func<RedisConnection, Task> func)
 {
     using (var conn = new RedisConnection("localhost"))
     {
         await conn.Open();
         await func(conn);
     }
 }
示例#22
0
 //
 // GET: /ABResults/
 public async Task<ActionResult> Index()
 {
     using (var conn = new RedisConnection("localhost"))
     {
         await conn.Open();
         return View(await conn.Keys.Find(0, "*"));
     }
 }
示例#23
0
 public void Clear()
 {
     using (var connection = new RedisConnection(Host, Port, -1, Password))
     {
         connection.Open().Wait();
         connection.Keys.Remove(Db, REDISMESSAGESKEY).Wait();
     }
 }
        public RedisActivityMonitorTests()
        {
            redis = new RedisConnection("localhost", allowAdmin: true);
            sut = new RedisActivityMonitor(redis);
            redis.Wait(redis.Open());

            redis.Wait(redis.Server.FlushDb(0));
        }
示例#25
0
 private static void WithRedis(Action<RedisConnection> action)
 {
     using (var conn = new RedisConnection("localhost"))
     {
         conn.Open();
         action(conn);
     }
 }
示例#26
0
 public void LogSuccess(string actionName, string viewName)
 {
     using (var conn = new RedisConnection("localhost"))
     {
         conn.Open();
         conn.Strings.Increment(0, String.Format("{0}.{1}.success", actionName, viewName));
     }
 }
 public RedisSessionItemHash(string sessionId, int timeoutMinutes, RedisConnection redisConnection)
     : base()
 {
     this.sessionId = sessionId;
     this.timeoutMinutes = timeoutMinutes;
     this.redis = redisConnection;
     SetTasks = new List<Task>();
 }
示例#28
0
 /// <summary>
 /// Builds the repository from scratch to ensure a cold start
 /// </summary>
 public void Build()
 {
     this.connection = new RedisConnection(this.connectionString.Split(':')[0], Convert.ToInt32(this.connectionString.Split(':')[1]), allowAdmin: true);
     Serializer.PrepareSerializer<University>();
     this.connection.Open();
     Task task = this.connection.Server.FlushDb(0);
     task.Wait();
 }
        SteamManager()
        {
            redis = new RedisConnection( "localhost" );

            // the main monitor will bootstrap the CM list
            mainMonitor = new MasterMonitor();

            monitors = new Dictionary<IPEndPoint, Monitor>();
        }
            public TestPackage(RedisConnection conn)
            {
                Redis = new RedisBooksleeveConnector(conn);
                var redisFS = new Resque.FailureService(new RedisBackendFactory(Redis));
                UnderTest = new Resque.Resque(new JobCreator(), redisFS, Redis);


                conn.Wait(conn.Keys.Remove(0, Redis.KeyInNamespace("queue:testQueue")));
            }
示例#31
0
 internal RedisTransaction(RedisConnection parent) : base(parent)
 {
     this.parent = parent;
 }
示例#32
0
        private static void ConnectToNodes(TextWriter log, string tieBreakerKey, int syncTimeout, int keepAlive, bool allowAdmin, string clientName, string[] arr, List <RedisConnection> connections, out Task <string>[] infos, out Task <string>[] aux, AuxMode mode)
        {
            TraceWriteTime("Infos");
            infos = new Task <string> [arr.Length];
            aux   = new Task <string> [arr.Length];
            var opens = new Task[arr.Length];

            for (int i = 0; i < arr.Length; i++)
            {
                var option = arr[i];
                if (string.IsNullOrWhiteSpace(option))
                {
                    continue;
                }

                RedisConnection conn = null;
                try
                {
                    var parts = option.Split(':');
                    if (parts.Length == 0)
                    {
                        continue;
                    }

                    string host = parts[0].Trim();
                    int    port = 6379, tmp;
                    if (parts.Length > 1 && int.TryParse(parts[1].Trim(), out tmp))
                    {
                        port = tmp;
                    }
                    conn      = new RedisConnection(host, port, syncTimeout: syncTimeout, allowAdmin: allowAdmin);
                    conn.Name = clientName;
                    log.WriteLine("Opening connection to {0}:{1}...", host, port);
                    if (keepAlive >= 0)
                    {
                        conn.SetKeepAlive(keepAlive);
                    }
                    opens[i] = conn.Open();
                    var info = conn.GetInfoImpl(null, false, false);
                    connections.Add(conn);
                    infos[i] = info;
                    switch (mode)
                    {
                    case AuxMode.TieBreakers:
                        if (tieBreakerKey != null)
                        {
                            aux[i] = conn.Strings.GetString(0, tieBreakerKey);
                        }
                        break;

                    case AuxMode.ClusterNodes:
                        aux[i] = conn.Cluster.GetNodes();
                        break;
                    }
                }
                catch (Exception ex)
                {
                    if (conn == null)
                    {
                        log.WriteLine("Error parsing option \"{0}\": {1}", option, ex.Message);
                    }
                    else
                    {
                        log.WriteLine("Error connecting: {0}", ex.Message);
                    }
                }
            }

            TraceWriteTime("Wait for infos");
            RedisConnectionBase.Trace("select-create", "wait...");
            var watch = new Stopwatch();

            foreach (Task task in infos.Concat(aux).Concat(opens))
            {
                if (task != null)
                {
                    try
                    {
                        int remaining = unchecked ((int)(syncTimeout - watch.ElapsedMilliseconds));
                        if (remaining > 0)
                        {
                            task.Wait(remaining);
                        }
                    }
                    catch { }
                }
            }
            watch.Stop();
            RedisConnectionBase.Trace("select-create", "complete");
        }
示例#33
0
 public MessageResultScript(RedisConnection connection, bool inferStrings, object state = null) : base(state)
 {
     this.connection   = connection;
     this.inferStrings = inferStrings;
 }
示例#34
0
        private static RedisConnection SelectAndCreateConnection(string configuration, TextWriter log,
                                                                 out string selectedConfiguration,
                                                                 out string[] availableEndpoints, bool autoMaster,
                                                                 string newMaster = null, string tieBreakerKey = null)
        {
            if (tieBreakerKey == null)
            {
                tieBreakerKey = "__Booksleeve_TieBreak";                        // default tie-breaker key
            }
            int    syncTimeout;
            bool   allowAdmin;
            string serviceName;
            string clientName;

            if (log == null)
            {
                log = new StringWriter();
            }
            string[] arr = GetConfigurationOptions(configuration, out syncTimeout, out allowAdmin, out serviceName,
                                                   out clientName);
            if (!string.IsNullOrWhiteSpace(newMaster))
            {
                allowAdmin = true;                                        // need this to diddle the slave/master config
            }
            log.WriteLine("{0} unique nodes specified", arr.Length);
            log.WriteLine("sync timeout: {0}ms, admin commands: {1}", syncTimeout,
                          allowAdmin ? "enabled" : "disabled");
            if (!string.IsNullOrEmpty(serviceName))
            {
                log.WriteLine("service: {0}", serviceName);
            }
            if (!string.IsNullOrEmpty(clientName))
            {
                log.WriteLine("client: {0}", clientName);
            }
            if (arr.Length == 0)
            {
                log.WriteLine("No nodes to consider");
                selectedConfiguration = null;
                availableEndpoints    = new string[0];
                return(null);
            }
            var             connections = new List <RedisConnection>(arr.Length);
            RedisConnection preferred   = null;

            try
            {
                var infos       = new List <Task <string> >(arr.Length);
                var tiebreakers = new List <Task <string> >(arr.Length);
                foreach (string option in arr)
                {
                    if (string.IsNullOrWhiteSpace(option))
                    {
                        continue;
                    }

                    RedisConnection conn = null;
                    try
                    {
                        string[] parts = option.Split(':');
                        if (parts.Length == 0)
                        {
                            continue;
                        }

                        string host = parts[0].Trim();
                        int    port = 6379, tmp;
                        if (parts.Length > 1 && int.TryParse(parts[1].Trim(), out tmp))
                        {
                            port = tmp;
                        }
                        conn      = new RedisConnection(host, port, syncTimeout: syncTimeout, allowAdmin: allowAdmin);
                        conn.Name = clientName;
                        log.WriteLine("Opening connection to {0}:{1}...", host, port);
                        conn.Open();
                        Task <string> info     = conn.GetInfo();
                        Task <string> tiebreak = conn.Strings.GetString(0, tieBreakerKey);
                        connections.Add(conn);
                        infos.Add(info);
                        tiebreakers.Add(tiebreak);
                    }
                    catch (Exception ex)
                    {
                        if (conn == null)
                        {
                            log.WriteLine("Error parsing option \"{0}\": {1}", option, ex.Message);
                        }
                        else
                        {
                            log.WriteLine("Error connecting: {0}", ex.Message);
                        }
                    }
                }
                List <RedisConnection> masters = new List <RedisConnection>(), slaves = new List <RedisConnection>();
                var breakerScores = new Dictionary <string, int>();
                foreach (var tiebreak in tiebreakers)
                {
                    try
                    {
                        if (tiebreak.Wait(syncTimeout))
                        {
                            string key = tiebreak.Result;
                            if (string.IsNullOrWhiteSpace(key))
                            {
                                continue;
                            }
                            int score;
                            if (breakerScores.TryGetValue(key, out score))
                            {
                                breakerScores[key] = score + 1;
                            }
                            else
                            {
                                breakerScores.Add(key, 1);
                            }
                        }
                    }
                    catch
                    {
                        /* if a node is down, that's fine too */
                    }
                }

                // see if any of our nodes are sentinels that know about the named service
                List <Tuple <RedisConnection, Task <Tuple <string, int> > > > sentinelNodes = null;
                foreach (RedisConnection conn in connections)
                {
                    // the "wait" we did during tie-breaker detection means we should now know what each server is
                    if (conn.ServerType == ServerType.Sentinel)
                    {
                        if (string.IsNullOrEmpty(serviceName))
                        {
                            log.WriteLine("Sentinel discovered, but no serviceName was specified; ignoring {0}:{1}",
                                          conn.Host, conn.Port);
                        }
                        else
                        {
                            log.WriteLine("Querying sentinel {0}:{1} for {2}...", conn.Host, conn.Port, serviceName);
                            if (sentinelNodes == null)
                            {
                                sentinelNodes = new List <Tuple <RedisConnection, Task <Tuple <string, int> > > >();
                            }
                            sentinelNodes.Add(Tuple.Create(conn, conn.QuerySentinelMaster(serviceName)));
                        }
                    }
                }

                // wait for sentinel results, if any
                if (sentinelNodes != null)
                {
                    var discoveredPairs = new Dictionary <Tuple <string, int>, int>();
                    foreach (var pair in sentinelNodes)
                    {
                        RedisConnection conn = pair.Item1;
                        try
                        {
                            Tuple <string, int> master = conn.Wait(pair.Item2);
                            if (master == null)
                            {
                                log.WriteLine("Sentinel {0}:{1} is not configured for {2}", conn.Host, conn.Port,
                                              serviceName);
                            }
                            else
                            {
                                log.WriteLine("Sentinel {0}:{1} nominates {2}:{3}", conn.Host, conn.Port, master.Item1,
                                              master.Item2);
                                int count;
                                if (discoveredPairs.TryGetValue(master, out count))
                                {
                                    count = 0;
                                }
                                discoveredPairs[master] = count + 1;
                            }
                        }
                        catch (Exception ex)
                        {
                            log.WriteLine("Error from sentinel {0}:{1} - {2}", conn.Host, conn.Port, ex.Message);
                        }
                    }
                    Tuple <string, int> finalChoice;
                    switch (discoveredPairs.Count)
                    {
                    case 0:
                        log.WriteLine("No sentinels nominated a master; unable to connect");
                        finalChoice = null;
                        break;

                    case 1:
                        finalChoice = discoveredPairs.Single().Key;
                        log.WriteLine("Sentinels nominated unanimous master: {0}:{1}", finalChoice.Item1,
                                      finalChoice.Item2);
                        break;

                    default:
                        finalChoice = discoveredPairs.OrderByDescending(kvp => kvp.Value).First().Key;
                        log.WriteLine("Sentinels nominated multiple masters; choosing arbitrarily: {0}:{1}",
                                      finalChoice.Item1, finalChoice.Item2);
                        break;
                    }

                    if (finalChoice != null)
                    {
                        RedisConnection toBeDisposed = null;
                        try
                        {
                            // good bet that in this scenario the input didn't specify any actual redis servers, so we'll assume open a new one
                            log.WriteLine("Opening nominated master: {0}:{1}...", finalChoice.Item1, finalChoice.Item2);
                            toBeDisposed = new RedisConnection(finalChoice.Item1, finalChoice.Item2,
                                                               allowAdmin: allowAdmin, syncTimeout: syncTimeout);
                            toBeDisposed.Wait(toBeDisposed.Open());
                            if (toBeDisposed.ServerType == ServerType.Master)
                            {
                                RedisConnection tmp = toBeDisposed;
                                toBeDisposed          = null; // so we don't dispose it
                                selectedConfiguration = tmp.Host + ":" + tmp.Port;
                                availableEndpoints    = new[] { selectedConfiguration };
                                return(tmp);
                            }
                            else
                            {
                                log.WriteLine("Server is {0} instead of a master", toBeDisposed.ServerType);
                            }
                        }
                        catch (Exception ex)
                        {
                            log.WriteLine("Error: {0}", ex.Message);
                        }
                        finally
                        {
                            // dispose if something went sour
                            using (toBeDisposed)
                            {
                            }
                        }
                    }
                    // something went south; BUT SENTINEL WINS TRUMPS; quit now
                    selectedConfiguration = null;
                    availableEndpoints    = new string[0];
                    return(null);
                }

                // check for tie-breakers (i.e. when we store which is the master)
                switch (breakerScores.Count)
                {
                case 0:
                    log.WriteLine("No tie-breakers found ({0})", tieBreakerKey);
                    break;

                case 1:
                    log.WriteLine("Tie-breaker ({0}) is unanimous: {1}", tieBreakerKey, breakerScores.Keys.Single());
                    break;

                default:
                    log.WriteLine("Ambiguous tie-breakers ({0}):", tieBreakerKey);
                    foreach (var kvp in breakerScores.OrderByDescending(x => x.Value))
                    {
                        log.WriteLine("\t{0}: {1}", kvp.Key, kvp.Value);
                    }
                    break;
                }

                for (int i = 0; i < connections.Count; i++)
                {
                    log.WriteLine("Reading configuration from {0}:{1}...", connections[i].Host, connections[i].Port);
                    try
                    {
                        if (!infos[i].Wait(syncTimeout))
                        {
                            log.WriteLine("\tTimeout fetching INFO");
                            continue;
                        }
                        var infoPairs = new StringDictionary();
                        using (var sr = new StringReader(infos[i].Result))
                        {
                            string line;
                            while ((line = sr.ReadLine()) != null)
                            {
                                int idx = line.IndexOf(':');
                                if (idx < 0)
                                {
                                    continue;
                                }
                                string key   = line.Substring(0, idx).Trim(),
                                       value = line.Substring(idx + 1, line.Length - (idx + 1)).Trim();
                                infoPairs[key] = value;
                            }
                        }
                        string role = infoPairs["role"];
                        switch (role)
                        {
                        case "slave":
                            log.WriteLine("\tServer is SLAVE of {0}:{1}",
                                          infoPairs["master_host"], infoPairs["master_port"]);
                            log.Write("\tLink is {0}, seen {1} seconds ago",
                                      infoPairs["master_link_status"], infoPairs["master_last_io_seconds_ago"]);
                            if (infoPairs["master_sync_in_progress"] == "1")
                            {
                                log.Write(" (sync is in progress)");
                            }
                            log.WriteLine();
                            slaves.Add(connections[i]);
                            break;

                        case "master":
                            log.WriteLine("\tServer is MASTER, with {0} slaves", infoPairs["connected_slaves"]);
                            masters.Add(connections[i]);
                            break;

                        default:
                            log.WriteLine("\tUnknown role: {0}", role);
                            break;
                        }
                        string tmp = infoPairs["connected_clients"];
                        int    clientCount, channelCount, patternCount;
                        if (string.IsNullOrWhiteSpace(tmp) || !int.TryParse(tmp, out clientCount))
                        {
                            clientCount = -1;
                        }
                        tmp = infoPairs["pubsub_channels"];
                        if (string.IsNullOrWhiteSpace(tmp) || !int.TryParse(tmp, out channelCount))
                        {
                            channelCount = -1;
                        }
                        tmp = infoPairs["pubsub_patterns"];
                        if (string.IsNullOrWhiteSpace(tmp) || !int.TryParse(tmp, out patternCount))
                        {
                            patternCount = -1;
                        }
                        log.WriteLine("\tClients: {0}; channels: {1}; patterns: {2}", clientCount, channelCount,
                                      patternCount);
                    }
                    catch (Exception ex)
                    {
                        log.WriteLine("\tError reading INFO results: {0}", ex.Message);
                    }
                }

                if (newMaster == null)
                {
                    switch (masters.Count)
                    {
                    case 0:
                        switch (slaves.Count)
                        {
                        case 0:
                            log.WriteLine("No masters or slaves found");
                            break;

                        case 1:
                            log.WriteLine("No masters found; selecting single slave");
                            preferred = slaves[0];
                            break;

                        default:
                            log.WriteLine("No masters found; considering {0} slaves...", slaves.Count);
                            preferred = SelectWithTieBreak(log, slaves, breakerScores);
                            break;
                        }
                        if (preferred != null)
                        {
                            if (autoMaster)
                            {
                                //LogException("Promoting redis SLAVE to MASTER");
                                log.WriteLine("Promoting slave to master...");
                                if (allowAdmin)
                                {
                                    // can do on this connection
                                    preferred.Wait(preferred.Server.MakeMaster());
                                }
                                else
                                {
                                    // need an admin connection for this
                                    using (
                                        var adminPreferred = new RedisConnection(preferred.Host, preferred.Port,
                                                                                 allowAdmin: true,
                                                                                 syncTimeout: syncTimeout))
                                    {
                                        adminPreferred.Open();
                                        adminPreferred.Wait(adminPreferred.Server.MakeMaster());
                                    }
                                }
                            }
                            else
                            {
                                log.WriteLine("Slave should be promoted to master (but not done yet)...");
                            }
                        }
                        break;

                    case 1:
                        log.WriteLine("One master found; selecting");
                        preferred = masters[0];
                        break;

                    default:
                        log.WriteLine("Considering {0} masters...", masters.Count);
                        preferred = SelectWithTieBreak(log, masters, breakerScores);
                        break;
                    }
                }
                else
                {
                    // we have been instructed to change master server
                    preferred = masters.Concat(slaves)
                                .FirstOrDefault(conn => (conn.Host + ":" + conn.Port) == newMaster);
                    if (preferred == null)
                    {
                        log.WriteLine("Selected new master not available: {0}", newMaster);
                    }
                    else
                    {
                        int errorCount = 0;
                        try
                        {
                            log.WriteLine("Promoting to master: {0}:{1}...", preferred.Host, preferred.Port);
                            preferred.Wait(preferred.Server.MakeMaster());
                            // if this is a master, we expect set/publish to work, even on 2.6
                            preferred.Strings.Set(0, tieBreakerKey, newMaster);
                            preferred.Wait(preferred.Publish(RedisMasterChangedChannel, newMaster));
                        }
                        catch (Exception ex)
                        {
                            log.WriteLine("\t{0}", ex.Message);
                            errorCount++;
                        }

                        if (errorCount == 0) // only make slaves if the master was happy
                        {
                            foreach (RedisConnection conn in masters.Concat(slaves))
                            {
                                if (conn == preferred)
                                {
                                    continue;                    // can't make self a slave!
                                }
                                try
                                {
                                    log.WriteLine("Enslaving: {0}:{1}...", conn.Host, conn.Port);

                                    // try to set the tie-breaker **first** in case of problems
                                    Task didSet = conn.Strings.Set(0, tieBreakerKey, newMaster);
                                    // and broadcast to anyone who thinks this is the master
                                    Task <long> didPublish = conn.Publish(RedisMasterChangedChannel, newMaster);
                                    // now make it a slave
                                    Task didEnslave = conn.Server.MakeSlave(preferred.Host, preferred.Port);
                                    // these are best-effort only; from 2.6, readonly slave servers may reject these commands
                                    try
                                    {
                                        conn.Wait(didSet);
                                    }
                                    catch
                                    {
                                    }
                                    try
                                    {
                                        conn.Wait(didPublish);
                                    }
                                    catch
                                    {
                                    }
                                    // but this one we'll log etc
                                    conn.Wait(didEnslave);
                                }
                                catch (Exception ex)
                                {
                                    log.WriteLine("\t{0}", ex.Message);
                                    errorCount++;
                                }
                            }
                        }
                        if (errorCount != 0)
                        {
                            log.WriteLine("Things didn't go smoothly; CHECK WHAT HAPPENED!");
                        }

                        // want the connection disposed etc
                        preferred = null;
                    }
                }

                if (preferred == null)
                {
                    selectedConfiguration = null;
                }
                else
                {
                    selectedConfiguration = preferred.Host + ":" + preferred.Port;
                    log.WriteLine("Selected server {0}", selectedConfiguration);
                }

                availableEndpoints = (from conn in masters.Concat(slaves)
                                      select conn.Host + ":" + conn.Port).ToArray();
                return(preferred);
            }
            finally
            {
                foreach (RedisConnection conn in connections)
                {
                    if (conn != null && conn != preferred)
                    {
                        try
                        {
                            conn.Dispose();
                        }
                        catch
                        {
                        }
                    }
                }
            }
        }
示例#35
0
 /// <summary>
 ///     Creates a child RedisConnection, such as for a RedisTransaction
 /// </summary>
 protected RedisConnection(RedisConnection parent) : base(
         parent.Host, parent.Port, parent.IOTimeout, parent.Password, int.MaxValue, parent.SyncTimeout)
 {
     allowAdmin = parent.allowAdmin;
     sent       = new Queue <RedisMessage>();
 }