protected override IEnumerable <EndpointAssignment> DoGetEndpointsForCall(string remoteAddress, string contract, object shardKey, Atom network, Atom binding) { var shard = (int)Data.ShardingUtils.ObjectToShardingID(shardKey) & CoreConsts.ABS_HASH_MASK; var key = new cacheKey(remoteAddress, contract, binding, network); if (!m_EPCache.TryGetValue(key, out var shards)) { shards = m_Endpoints.Where(ep => remoteAddress.MatchPattern(ep.RemoteAddress) && contract.MatchPattern(ep.Contract) && ep.Binding == binding && ep.Network == network ).GroupBy(ep => ep.Shard) .OrderBy(g => g.Key) .Select(g => g.OrderBy(ep => ep.ShardOrder) .Select(ep => new EndpointAssignment(ep, remoteAddress, contract)).ToArray()) .ToArray(); if (shards.Length == 0) { return(Enumerable.Empty <EndpointAssignment>()); } var dict = new Dictionary <cacheKey, EndpointAssignment[][]>(); dict[key] = shards; Thread.MemoryBarrier(); m_EPCache = dict;//atomic } var result = shards[shard % shards.Length]; return(result); }
protected virtual EndpointAssignment[][] DoGetEndpointsForAllShardsArray(string remoteAddress, string contract, Atom network, Atom binding) { var key = new cacheKey(remoteAddress, contract, binding, network); if (!m_EPCache.TryGetValue(key, out var shards)) { shards = m_Endpoints.Where(ep => remoteAddress.MatchPattern(ep.RemoteAddress) && contract.MatchPattern(ep.Contract) && ep.Binding == binding && ep.Network == network ).GroupBy(ep => ep.Shard) .OrderBy(g => g.Key) .Select(g => g.OrderBy(ep => ep.ShardOrder) .Select(ep => new EndpointAssignment(ep, remoteAddress, contract)).ToArray()) .ToArray(); if (shards.Length == 0) { return(null); } var dict = new Dictionary <cacheKey, EndpointAssignment[][]>(m_EPCache); dict[key] = shards; Thread.MemoryBarrier(); m_EPCache = dict;//atomic } return(shards); }