public static async Task<Cluster> From(string initialHost, int initialPort, ClusterConfiguration configuration) { //TODO: This isn't very resilient... what if the configured master is gone? We should be able to specify multiple... var initialConnection = await Connection.ConnectAsync(initialHost, initialPort, configuration.Connections); //TODO: We can figure out the complete picture (masters, slaves, etc) from CLUSTER NODES command. //Setting up each node (inside ClusterNode.ConnectAsync - further down) is wasteful. var clusterNodesCommand = Command.From("CLUSTER", "NODES"); var clusterInfoResponse = await clusterNodesCommand.SendAsync(initialConnection); if (clusterInfoResponse.IsError) throw ExceptionBecause.Cluster.GotErrorResponseFromClusterInfo(clusterInfoResponse); if (clusterInfoResponse.Value.IsArray) throw ExceptionBecause.MalformedData.InClusterInfo(clusterInfoResponse); var otherNodes = clusterInfoResponse.Value.ToString() .Split(new [] { '\n' }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.Split(' ')) .Where(s => s[2].Contains("master")) .Select(s => { var hostAndPort = s[1].Split(':'); var host = hostAndPort[0]; var port = int.Parse(hostAndPort[1]); var slotRange = HashSlotRange.From(s.Skip(8).ToArray()); return Node .ConnectAsync(host, port, configuration.ConnectionPools, configuration.Connections) .ContinueWith(node => (IClusterNode) new ClusterNode(node.Result, slotRange)); }); var clusterNodes = await Task.WhenAll(otherNodes); return new Cluster(new NodeSet(clusterNodes.ToList(), configuration), configuration); }
protected Cluster(INodeSet nodes, ClusterConfiguration configuration) { _nodes = nodes; _configuration = configuration; }