Пример #1
0
 /**
  * <summary>
  * Creates a facade.</summary>
  *
  * <param name="clientId">Client identifier.</param>
  * <param name="srvAddr">Server address this connection connected to.</param>
  * <param name="sslCtx">SSL context to use if SSL is enabled, <c>null</c> otherwise.</param>
  * <param name="credentials">Authentication credentials</param>
  * <param name="top">Topology.</param>
  */
 protected GridClientConnectionAdapter(Guid clientId, IPEndPoint srvAddr, IGridClientSslContext sslCtx,
                                       Object credentials, GridClientTopology top)
 {
     this.ClientId      = clientId;
     this.ServerAddress = srvAddr;
     this.Top           = top;
     this.Credentials   = credentials;
     this.SslCtx        = sslCtx;
 }
        /**
         * <summary>
         * Constructs connection manager.</summary>
         *
         * <param name="clientId">Client ID.</param>
         * <param name="top">Topology.</param>
         * <param name="credentials">Connection credentials.</param>
         * <param name="proto">Connection protocol.</param>
         * <param name="sslCtx">SSL context to enable secured connection or <c>null</c> to use unsecured one.</param>
         * <param name="connectTimeout">TCP connection timeout.</param>
         */
        public GridClientConnectionManager(Guid clientId, GridClientTopology top,
            Object credentials, GridClientProtocol proto, IGridClientSslContext sslCtx, int connectTimeout)
        {
            Dbg.Assert(clientId != null, "clientId != null");
            Dbg.Assert(top != null, "top != null");
            Dbg.Assert(connectTimeout >= 0, "connectTimeout > 0");

            this.clientId = clientId;
            this.credentials = credentials;
            this.top = top;
            this.proto = proto;
            this.sslCtx = sslCtx;
            this.connectTimeout = connectTimeout;
        }
Пример #3
0
        /**
         * <summary>
         * Tries to refresh node on every possible connection in topology.</summary>
         *
         * <param name="nodeId">Node id to check.</param>
         * <returns><c>True</c> if response was received, <c>null</c> if either <c>null</c> response received
         * or no nodes can be contacted at all.</returns>
         * <exception cref="GridClientClosedException">If client was closed manually.</exception>
         */
        protected bool CheckNodeAlive(Guid nodeId)
        {
            GridClientConnectionManager connMgr = cfg.ConnectionManager;
            GridClientTopology          top     = cfg.Topology;

            // Try to get node information on any of the connections possible.
            foreach (N node in top.Nodes())
            {
                try {
                    // Do not try to connect to the same node.
                    if (node.Id.Equals(nodeId))
                    {
                        continue;
                    }

                    // Get connection to node DIFFER from the requested nodeId.
                    IGridClientConnection conn = connMgr.connection(node);

                    try {
                        // Get node via DIFFERENT grid node to ensure the grid knows about node with nodeId (it is alive).
                        N target = conn.Node(nodeId, false, false, node.Id).Result;

                        // If requested node not found...
                        if (target == null)
                        {
                            top.NodeFailed(nodeId);
                        }

                        return(target != null);
                    }
                    catch (GridClientConnectionResetException e) {
                        connMgr.onFacadeFailed(node, conn, e);
                    }
                    catch (GridClientClosedException) {
                        throw;
                    }
                    catch (GridClientException e) {
                        // Future failed, so connection exception have already been handled.
                        Dbg.WriteLine("Could not receive node by its id [nodeId={0}, e={1}]", nodeId, e);
                    }
                }
                catch (GridClientServerUnreachableException e) {
                    // Try next node.
                    Dbg.WriteLine("Could not receive node by its id [nodeId={0}, e={1}]", nodeId, e);
                }
            }

            return(false);
        }
Пример #4
0
        /**
         * <summary>
         * Constructs connection manager.</summary>
         *
         * <param name="clientId">Client ID.</param>
         * <param name="top">Topology.</param>
         * <param name="routers">Routers or empty collection to use endpoints from topology info.</param>
         * <param name="credentials">Connection credentials.</param>
         * <param name="proto">Connection protocol.</param>
         * <param name="sslCtx">SSL context to enable secured connection or <c>null</c> to use unsecured one.</param>
         * <param name="connectTimeout">TCP connection timeout.</param>
         */
        public GridClientConnectionManager(Guid clientId, GridClientTopology top, ICollection <IPEndPoint> routers,
                                           Object credentials, GridClientProtocol proto, IGridClientSslContext sslCtx, int connectTimeout)
        {
            Dbg.Assert(clientId != null, "clientId != null");
            Dbg.Assert(top != null, "top != null");
            Dbg.Assert(routers != null, "routers != null");
            Dbg.Assert(connectTimeout >= 0, "connectTimeout > 0");

            this.clientId       = clientId;
            this.credentials    = credentials;
            this.top            = top;
            this.routers        = routers;
            this.proto          = proto;
            this.sslCtx         = sslCtx;
            this.connectTimeout = connectTimeout;
        }
        /**
         * <summary>
         * Creates HTTP client connection.</summary>
         *
         * <param name="clientId">Client identifier.</param>
         * <param name="srvAddr">Server address on which HTTP REST handler resides.</param>
         * <param name="sslCtx">SSL context to use if SSL is enabled, <c>null</c> otherwise.</param>
         * <param name="credentials">Client credentials.</param>
         * <param name="top">Topology to use.</param>
         * <exception cref="System.IO.IOException">If input-output exception occurs.</exception>
         */
        public GridClientHttpConnection(Guid clientId, IPEndPoint srvAddr, IGridClientSslContext sslCtx,
                                        Object credentials, GridClientTopology top)
            : base(clientId, srvAddr, sslCtx, credentials, top)
        {
            // Validate server is available.
            var args = new Dictionary <String, Object>();

            args.Add("cmd", "noop");

            try {
                LoadString(args, null);
            }
            catch (System.Net.WebException e) {
                if (e.InnerException is System.Security.Authentication.AuthenticationException)
                {
                    Dbg.Print("To use invalid certificates for secured HTTP client protocol provide system-wide" +
                              " setting: System.Net.ServicePointManager.ServerCertificateValidationCallback");
                }

                throw; // Re-throw base exception.
            }
        }
Пример #6
0
        /**
         * <summary>
         * Creates a client facade, tries to connect to remote server, in case
         * of success starts reader thread.</summary>
         *
         * <param name="clientId">Client identifier.</param>
         * <param name="srvAddr">Server to connect to.</param>
         * <param name="sslCtx">SSL context to use if SSL is enabled, <c>null</c> otherwise.</param>
         * <param name="connectTimeout">Connect timeout.</param>
         * <param name="marshaller">Marshaller to use in communication.</param>
         * <param name="credentials">Client credentials.</param>
         * <param name="top">Topology instance.</param>
         * <exception cref="IOException">If connection could not be established.</exception>
         */
        public GridClientTcpConnection(Guid clientId, IPEndPoint srvAddr, IGridClientSslContext sslCtx, int connectTimeout,
                                       IGridClientMarshaller marshaller, Object credentials, GridClientTopology top)
            : base(clientId, srvAddr, sslCtx, credentials, top)
        {
            this.marshaller = marshaller;

            if (connectTimeout <= 0)
            {
                connectTimeout = (int)SOCK_READ_TIMEOUT.TotalMilliseconds;
            }

            Dbg.Assert(connectTimeout > 0, "connectTimeout > 0");

            int       retries    = 3;
            Exception firstCause = null;

            do
            {
                if (retries-- <= 0)
                {
                    throw new IOException("Cannot open socket for address: " + srvAddr, firstCause);
                }

                if (tcp != null)
                {
                    Dbg.WriteLine("Connection to address {0} failed, try re-connect", srvAddr);
                }

                try {
                    // Create a TCP/IP client socket.
                    tcp = new TcpClient();

                    tcp.ReceiveTimeout = connectTimeout;
                    tcp.SendTimeout    = connectTimeout;

                    // Open connection.
                    tcp.Connect(srvAddr);
                }
                catch (Exception x) {
                    if (firstCause == null)
                    {
                        firstCause = x;
                    }

                    if (tcp != null && tcp.Connected)
                    {
                        tcp.Close();
                    }

                    continue;
                }
            } while (!tcp.Connected);

            if (sslCtx == null)
            {
                stream = tcp.GetStream();
            }
            else
            {
                stream = sslCtx.CreateStream(tcp);

                lock (stream) {
                    // Flush client authentication packets (if any).
                    stream.Flush();
                }
            }

            // Avoid immediate attempt to close by idle.
            lastPacketSndTime = lastPacketRcvTime = lastPingSndTime = lastPingRcvTime = U.Now;

            rdr = new Thread(readPackets);

            rdr.Name = "grid-tcp-connection--client#" + clientId + "--addr#" + srvAddr;

            //Dbg.WriteLine("Start thread: " + rdr.Name);

            rdr.Start();
        }
Пример #7
0
        /**
         * <summary>
         * Creates a new client based on a given configuration.</summary>
         *
         * <param name="id">Client identifier.</param>
         * <param name="cfg0">Client configuration.</param>
         * <exception cref="GridClientException">If client configuration is incorrect.</exception>
         * <exception cref="GridClientServerUnreachableException">If none of the servers specified in configuration can be reached.</exception>
         */
        public GridClientImpl(Guid id, IGridClientConfiguration cfg0)
        {
            Id = id;

            cfg = new GridClientConfiguration(cfg0);

            ICollection<IPEndPoint> srvs = new List<IPEndPoint>(cfg.Servers.Count);

            foreach (String srvStr in cfg.Servers) {
                String[] split = srvStr.Split(":".ToCharArray());

                if (split.Length != 2)
                    throw new GridClientException("Failed to create client (invalid endpoint format, expected 'IPv4:Port'): " + srvStr);

                IPAddress addr;

                if (!IPAddress.TryParse(split[0], out addr))
                    throw new GridClientException("Failed to create client (invalid address format): " + srvStr);

                int port;

                if (!int.TryParse(split[1], out port))
                    throw new GridClientException("Failed to create client (invalid port format): " + srvStr);

                srvs.Add(new IPEndPoint(addr, port));
            }

            top = new GridClientTopology(id, cfg.IsTopologyCacheEnabled);

            Action<Object> addTopLsnr = o => {
                var lsnr = o as IGridClientTopologyListener;

                if (lsnr != null)
                    top.AddTopologyListener(lsnr);
            };

            // Add to topology as listeners.
            foreach (IGridClientDataConfiguration dataCfg in cfg.DataConfigurations)
                addTopLsnr(dataCfg.Affinity);

            addTopLsnr(cfg.Balancer);
            addTopLsnr(topUpdateBalancer);

            connMgr = new GridClientConnectionManager(Id, top, cfg.Credentials, cfg.Protocol,
                cfg.SslContext, cfg.ConnectTimeout);

            int retries = 3;

            while (true) {
                IGridClientConnection conn = null;

                try {
                    // Create connection to a server from the list of endpoints.
                    conn = connMgr.connection(srvs);

                    // Request topology at start to determine which node we connected to.
                    // Also this request validates TCP connection is alive.
                    conn.Topology(false, false).WaitDone();

                    break;
                }
                catch (GridClientAuthenticationException) {
                    if (conn != null)
                        conn.Close(false);

                    top.Dispose();

                    throw;
                }
                catch (GridClientException e) {
                    if (conn != null)
                        conn.Close(false);

                    if (retries-- <= 0) {
                        top.Dispose();

                        throw new GridClientException("Failed to update grid topology.", e);
                    }
                }
            }

            IDictionary<String, GridClientCacheMode> overallCaches = new GridClientNullDictionary<String, GridClientCacheMode>();

            // Topology is now updated, so we can identify current connection.
            foreach (GridClientNodeImpl node in top.Nodes())
                foreach (KeyValuePair<String, GridClientCacheMode> pair in node.Caches)
                    overallCaches[pair.Key] = pair.Value;

            foreach (KeyValuePair<String, GridClientCacheMode> entry in overallCaches)
                if (Affinity(entry.Key) is GridClientPartitionedAffinity && entry.Value != GridClientCacheMode.Partitioned)
                    Dbg.WriteLine(typeof(GridClientPartitionedAffinity) + " is used for a cache configured " +
                        "for non-partitioned mode [cacheName=" + entry.Key + ", cacheMode=" + entry.Value + ']');

            idleCheckThread = new Thread(checkIdle);

            idleCheckThread.Name = "grid-check-idle-worker--client#" + id;

            //Dbg.WriteLine("Start thread: " + idleCheckThread.Name);

            idleCheckThread.Start();

            topUpdateThread = new Thread(updateTopology);

            topUpdateThread.Name = "grid-topology-update-worker--client#" + id;

            //Dbg.WriteLine("Start thread: " + topUpdateThread.Name);

            topUpdateThread.Start();

            _compute = new GridClientComputeImpl(this, null, null, cfg.Balancer);
        }
Пример #8
0
        /**
         * <summary>
         * Creates a new client based on a given configuration.</summary>
         *
         * <param name="id">Client identifier.</param>
         * <param name="cfg0">Client configuration.</param>
         * <exception cref="GridClientException">If client configuration is incorrect.</exception>
         * <exception cref="GridClientServerUnreachableException">If none of the servers specified in configuration can be reached.</exception>
         */
        public GridClientImpl(Guid id, IGridClientConfiguration cfg0)
        {
            Id = id;

            cfg = new GridClientConfiguration(cfg0);

            ICollection <IPEndPoint> srvs    = ParseServers(cfg.Servers);
            ICollection <IPEndPoint> routers = ParseServers(cfg.Routers);

            top = new GridClientTopology(id, cfg.IsTopologyCacheEnabled);

            Action <Object> addTopLsnr = o => {
                var lsnr = o as IGridClientTopologyListener;

                if (lsnr != null)
                {
                    top.AddTopologyListener(lsnr);
                }
            };

            // Add to topology as listeners.
            foreach (IGridClientDataConfiguration dataCfg in cfg.DataConfigurations)
            {
                addTopLsnr(dataCfg.Affinity);
            }

            addTopLsnr(cfg.Balancer);
            addTopLsnr(topUpdateBalancer);

            if (srvs.Count == 0)
            {
                // Use routers for initial connection.
                srvs = routers;
            }
            else
            {
                // Disable routers for connection manager.
                routers = new HashSet <IPEndPoint>();
            }

            connMgr = new GridClientConnectionManager(Id, top, routers, cfg.Credentials, cfg.Protocol, cfg.SslContext, cfg.ConnectTimeout);

            int retries = 3;

            while (true)
            {
                IGridClientConnection conn = null;

                try {
                    // Create connection to a server from the list of endpoints.
                    conn = connMgr.connection(srvs);

                    // Request topology at start to determine which node we connected to.
                    // Also this request validates TCP connection is alive.
                    conn.Topology(false, false, Guid.Empty).WaitDone();

                    break;
                }
                catch (GridClientAuthenticationException) {
                    if (conn != null)
                    {
                        conn.Close(false);
                    }

                    top.Dispose();

                    throw;
                }
                catch (GridClientException e) {
                    if (conn != null)
                    {
                        conn.Close(false);
                    }

                    if (retries-- <= 0)
                    {
                        top.Dispose();

                        throw new GridClientException("Failed to update grid topology.", e);
                    }
                }
            }

            IDictionary <String, GridClientCacheMode> overallCaches = new GridClientNullDictionary <String, GridClientCacheMode>();

            // Topology is now updated, so we can identify current connection.
            foreach (GridClientNodeImpl node in top.Nodes())
            {
                foreach (KeyValuePair <String, GridClientCacheMode> pair in node.Caches)
                {
                    overallCaches[pair.Key] = pair.Value;
                }
            }

            foreach (KeyValuePair <String, GridClientCacheMode> entry in overallCaches)
            {
                if (Affinity(entry.Key) is GridClientPartitionAffinity && entry.Value != GridClientCacheMode.Partitioned)
                {
                    Dbg.WriteLine(typeof(GridClientPartitionAffinity) + " is used for a cache configured " +
                                  "for non-partitioned mode [cacheName=" + entry.Key + ", cacheMode=" + entry.Value + ']');
                }
            }

            idleCheckThread = new Thread(checkIdle);

            idleCheckThread.Name = "grid-check-idle-worker--client#" + id;

            idleCheckThread.Start();

            topUpdateThread = new Thread(updateTopology);

            topUpdateThread.Name = "grid-topology-update-worker--client#" + id;

            topUpdateThread.Start();

            _compute = new GridClientComputeImpl(this, null, null, cfg.Balancer);

            Dbg.WriteLine("Client started. Id: " + Id);
        }
Пример #9
0
        /**
         * <summary>
         * Creates a new client based on a given configuration.</summary>
         *
         * <param name="id">Client identifier.</param>
         * <param name="cfg0">Client configuration.</param>
         * <exception cref="GridClientException">If client configuration is incorrect.</exception>
         * <exception cref="GridClientServerUnreachableException">If none of the servers specified in configuration can be reached.</exception>
         */
        public GridClientImpl(Guid id, IGridClientConfiguration cfg0)
        {
            Id = id;

            cfg = new GridClientConfiguration(cfg0);

            ICollection<IPEndPoint> srvs = ParseServers(cfg.Servers);
            ICollection<IPEndPoint> routers = ParseServers(cfg.Routers);

            top = new GridClientTopology(id, cfg.IsTopologyCacheEnabled);

            Action<Object> addTopLsnr = o => {
                var lsnr = o as IGridClientTopologyListener;

                if (lsnr != null)
                    top.AddTopologyListener(lsnr);
            };

            // Add to topology as listeners.
            foreach (IGridClientDataConfiguration dataCfg in cfg.DataConfigurations)
                addTopLsnr(dataCfg.Affinity);

            addTopLsnr(cfg.Balancer);
            addTopLsnr(topUpdateBalancer);

            if (srvs.Count == 0)
                // Use routers for initial connection.
                srvs = routers;
            else
                // Disable routers for connection manager.
                routers = new HashSet<IPEndPoint>();

            connMgr = new GridClientConnectionManager(Id, top, routers, cfg.Credentials, cfg.Protocol, cfg.SslContext, cfg.ConnectTimeout);

            int retries = 3;

            while (true) {
                IGridClientConnection conn = null;

                try {
                    // Create connection to a server from the list of endpoints.
                    conn = connMgr.connection(srvs);

                    // Request topology at start to determine which node we connected to.
                    // Also this request validates TCP connection is alive.
                    conn.Topology(false, false, Guid.Empty).WaitDone();

                    break;
                }
                catch (GridClientAuthenticationException) {
                    if (conn != null)
                        conn.Close(false);

                    top.Dispose();

                    throw;
                }
                catch (GridClientException e) {
                    if (conn != null)
                        conn.Close(false);

                    if (retries-- <= 0) {
                        top.Dispose();

                        throw new GridClientException("Failed to update grid topology.", e);
                    }
                }
            }

            IDictionary<String, GridClientCacheMode> overallCaches = new GridClientNullDictionary<String, GridClientCacheMode>();

            // Topology is now updated, so we can identify current connection.
            foreach (GridClientNodeImpl node in top.Nodes())
                foreach (KeyValuePair<String, GridClientCacheMode> pair in node.Caches)
                    overallCaches[pair.Key] = pair.Value;

            foreach (KeyValuePair<String, GridClientCacheMode> entry in overallCaches)
                if (Affinity(entry.Key) is GridClientPartitionAffinity && entry.Value != GridClientCacheMode.Partitioned)
                    Dbg.WriteLine(typeof(GridClientPartitionAffinity) + " is used for a cache configured " +
                        "for non-partitioned mode [cacheName=" + entry.Key + ", cacheMode=" + entry.Value + ']');

            idleCheckThread = new Thread(checkIdle);

            idleCheckThread.Name = "grid-check-idle-worker--client#" + id;

            idleCheckThread.Start();

            topUpdateThread = new Thread(updateTopology);

            topUpdateThread.Name = "grid-topology-update-worker--client#" + id;

            topUpdateThread.Start();

            _compute = new GridClientComputeImpl(this, null, null, cfg.Balancer);

            Dbg.WriteLine("Client started. Id: " + Id);
        }