/** * <summary> * Updates topology if cache enabled. If cache is disabled, returns original node.</summary> * * <param name="node">Converted rest server response.</param> * <returns>Node in topology.</returns> */ public N UpdateNode(N node) { A.NotNull(node, "node"); busyLock.AcquireWriterLock(Timeout.Infinite); try { bool nodeAdded = !_nodes.ContainsKey(node.Id); // We update the whole topology if node was not in topology or we cache metrics. if (nodeAdded || topCache) { node = ClearAttributes(node); _nodes[node.Id] = node; } if (nodeAdded) { FireEvents(new TopologyEvent[] { new TopologyEvent(true, node) }); } return(node); } finally { busyLock.ReleaseWriterLock(); } }
/** * <summary> * This method executes request to a communication layer and handles connection error, if it occurs. Server * is picked up according to the projection affinity and key given. Connection will be made with the node * on which key is cached. In case of communication exception client instance is notified and new instance * of client is created. If none of servers can be reached, an exception is thrown.</summary> * * <param name="c">Closure to be executed.</param> * <param name="cacheName">Cache name for which mapped node will be calculated.</param> * <param name="affKey">Affinity key.</param> * <returns>Closure result.</returns> */ protected IGridClientFuture <TRes> WithReconnectHandling <TRes>(Func <IGridClientConnection, Guid, IGridClientFuture <TRes> > c, String cacheName, Object affKey) { IGridClientDataAffinity affinity = cfg.Affinity(cacheName); // If pinned (fixed-nodes) or no affinity provided use balancer. if (_nodes != null || affinity == null) { return(WithReconnectHandling(c)); } try { IList <N> prjNodes = ProjectionNodes(); if (prjNodes.Count == 0) { throw new GridClientServerUnreachableException("Failed to get affinity node" + " (no nodes in topology were accepted by the filter): " + _filter); } N node = affinity.Node(affKey, prjNodes); GridClientConnectionManager connMgr = cfg.ConnectionManager; for (int i = 0; i < RetryCount; i++) { IGridClientConnection conn = null; try { conn = connMgr.connection(node); return(c(conn, node.Id)); } catch (GridClientConnectionIdleClosedException e) { connMgr.onFacadeFailed(node, conn, e); } catch (GridClientConnectionResetException e) { connMgr.onFacadeFailed(node, conn, e); if (!CheckNodeAlive(node.Id)) { throw new GridClientServerUnreachableException("Failed to communicate with mapped grid node" + " for given affinity key (node left the grid)" + " [nodeId=" + node.Id + ", affKey=" + affKey + ']'); } } } throw new GridClientServerUnreachableException("Failed to communicate with mapped grid node for given affinity " + "key (did node left the grid?) [nodeId=" + node.Id + ", affKey=" + affKey + ']'); } catch (GridClientException e) { return(new GridClientFinishedFuture <TRes>(() => { throw e; })); } }
/** <inheritdoc /> */ public IGridClientData PinNodes(N node, params N[] nodes) { LinkedList <N> n = new LinkedList <N>(); n.AddFirst(node); if (nodes != null) { n.AddAll(nodes); } return(CreateProjection(n, null, null)); }
/** * <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> * This method executes request to a communication layer and handles connection error, if it occurs. * In case of communication exception client instance is notified and new instance of client is created. * If none of the grid servers can be reached, an exception is thrown.</summary> * * <param name="c">Closure to be executed.</param> * <returns>Closure result.</returns> */ protected IGridClientFuture <TRes> WithReconnectHandling <TRes>(Func <IGridClientConnection, Guid, IGridClientFuture <TRes> > c) { try { N node = null; bool changeNode = false; GridClientConnectionManager connMgr = cfg.ConnectionManager; for (int i = 0; i < RetryCount; i++) { if (node == null || changeNode) { node = BalancedNode(); } IGridClientConnection conn = null; try { conn = connMgr.connection(node); return(c(conn, node.Id)); } catch (GridClientConnectionIdleClosedException e) { connMgr.onFacadeFailed(node, conn, e); // It's ok, just reconnect to the same node. changeNode = false; } catch (GridClientConnectionResetException e) { connMgr.onFacadeFailed(node, conn, e); changeNode = true; } } throw new GridClientServerUnreachableException("Failed to communicate with grid nodes " + "(maximum count of retries reached)."); } catch (GridClientException e) { return(new GridClientFinishedFuture <TRes>(() => { throw e; })); } }
/** * <summary> * Clears attributes and metrics map in case if node cache is disabled.</summary> * * <param name="node">Node to be cleared.</param> * <returns>The same node if cache is enabled or node contains no attributes and metrics,</returns> * otherwise will return new node without attributes and metrics. */ private N ClearAttributes(N node) { if (topCache || (node.Attributes.Count == 0 && node.Metrics == null)) { return(node); } // Fill all fields but attributes and metrics since we do not cache them. GridClientNodeImpl updated = new GridClientNodeImpl(node.Id); updated.TcpAddresses.AddAll <String>(node.TcpAddresses); updated.TcpHostNames.AddAll <String>(node.TcpHostNames); updated.JettyAddresses.AddAll <String>(node.JettyAddresses); updated.JettyHostNames.AddAll <String>(node.JettyHostNames); updated.TcpPort = node.TcpPort; updated.HttpPort = node.HttpPort; updated.ConsistentId = node.ConsistentId; updated.Metrics = null; updated.Caches.AddAll <KeyValuePair <String, GridClientCacheMode> >(node.Caches); return(updated); }
/** * <summary> * Creates a new event.</summary> * * <param name="added">If <c>true</c>, indicates that node was added to topology.</param> * If <c>false</c>, indicates that node was removed. * <param name="node">Added or removed node.</param> */ public TopologyEvent(bool added, N node) { this.Added = added; this.Node = node; }
/** * <summary> * Clears attributes and metrics map in case if node cache is disabled.</summary> * * <param name="node">Node to be cleared.</param> * <returns>The same node if cache is enabled or node contains no attributes and metrics,</returns> * otherwise will return new node without attributes and metrics. */ private N ClearAttributes(N node) { if (topCache || (node.Attributes.Count == 0 && node.Metrics == null)) return node; // Fill all fields but attributes and metrics since we do not cache them. GridClientNodeImpl updated = new GridClientNodeImpl(node.Id); updated.TcpAddresses.AddAll<String>(node.TcpAddresses); updated.TcpHostNames.AddAll<String>(node.TcpHostNames); updated.JettyAddresses.AddAll<String>(node.JettyAddresses); updated.JettyHostNames.AddAll<String>(node.JettyHostNames); updated.TcpPort = node.TcpPort; updated.HttpPort = node.HttpPort; updated.ConsistentId= node.ConsistentId; updated.Metrics = null; updated.Caches.AddAll<KeyValuePair<String, GridClientCacheMode>>(node.Caches); return updated; }
/** * <summary> * Updates topology if cache enabled. If cache is disabled, returns original node.</summary> * * <param name="node">Converted rest server response.</param> * <returns>Node in topology.</returns> */ public N UpdateNode(N node) { A.NotNull(node, "node"); busyLock.AcquireWriterLock(Timeout.Infinite); try { bool nodeAdded = !_nodes.ContainsKey(node.Id); // We update the whole topology if node was not in topology or we cache metrics. if (nodeAdded || topCache) { node = ClearAttributes(node); _nodes[node.Id] = node; } if (nodeAdded) FireEvents(new TopologyEvent[] { new TopologyEvent(true, node) }); return node; } finally { busyLock.ReleaseWriterLock(); } }
/** <inheritdoc /> */ public IGridClientCompute Projection(N node) { return(CreateProjection(U.List(node), null, null)); }