public override async Task <bool> UpdateTopologyAsync(UpdateTopologyParameters parameters) { if (parameters is null) { throw new ArgumentNullException(nameof(parameters)); } if (Disposed) { return(false); } var lockTaken = await _clusterTopologySemaphore.WaitAsync(parameters.TimeoutInMs).ConfigureAwait(false); if (lockTaken == false) { return(false); } try { if (Disposed) { return(false); } using (ContextPool.AllocateOperationContext(out JsonOperationContext context)) { var command = new GetClusterTopologyCommand(parameters.DebugTag); await ExecuteAsync(parameters.Node, null, context, command, shouldRetry : false, sessionInfo : null, token : CancellationToken.None).ConfigureAwait(false); ClusterTopologyLocalCache.TrySaving(TopologyHash, command.Result, Conventions, context); var results = command.Result; var newTopology = new Topology { Nodes = new List <ServerNode>( from member in results.Topology.Members select new ServerNode { Url = member.Value, ClusterTag = member.Key } ), Etag = results.Etag }; TopologyEtag = results.Etag; if (_nodeSelector == null) { _nodeSelector = new NodeSelector(newTopology); if (Conventions.ReadBalanceBehavior == ReadBalanceBehavior.FastestNode) { _nodeSelector.ScheduleSpeedTest(); } } else if (_nodeSelector.OnUpdateTopology(newTopology, forceUpdate: parameters.ForceUpdate)) { DisposeAllFailedNodesTimers(); if (Conventions.ReadBalanceBehavior == ReadBalanceBehavior.FastestNode) { _nodeSelector.ScheduleSpeedTest(); } } OnTopologyUpdated(newTopology); } } catch (Exception) { if (Disposed == false) { throw; } } finally { _clusterTopologySemaphore.Release(); } return(true); }
public NodeSelector(Topology topology) { _state = new NodeSelectorState(topology); }