/** * <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; }
/** * <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); }
/** * <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. } }
/** * <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(); }
/** * <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); }
/** * <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); }
/** * <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); }