// ********************************************************************** // // Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** namespace IceDiscovery { using System.Collections.Generic; using System.Threading.Tasks; class LocatorRegistryI : Ice.LocatorRegistryDisp_ { public LocatorRegistryI(Ice.Communicator com) { _wellKnownProxy = com.stringToProxy("p").ice_locator(null).ice_router(null).ice_collocationOptimized(true); } public override Task setAdapterDirectProxyAsync(string adapterId, Ice.ObjectPrx proxy, Ice.Current current) { lock(this) { if(proxy != null) { _adapters.Add(adapterId, proxy); } else { _adapters.Remove(adapterId); } } return null; } public override Task setReplicatedAdapterDirectProxyAsync(string adapterId, string replicaGroupId, Ice.ObjectPrx proxy, Ice.Current current) { lock(this) { if(proxy != null) { _adapters.Add(adapterId, proxy); HashSet adapterIds; if(!_replicaGroups.TryGetValue(replicaGroupId, out adapterIds)) { adapterIds = new HashSet(); _replicaGroups.Add(replicaGroupId, adapterIds); } adapterIds.Add(adapterId); } else { _adapters.Remove(adapterId); HashSet adapterIds; if(_replicaGroups.TryGetValue(replicaGroupId, out adapterIds)) { adapterIds.Remove(adapterId); if(adapterIds.Count == 0) { _replicaGroups.Remove(replicaGroupId); } } } } return null; } public override Task setServerProcessProxyAsync(string id, Ice.ProcessPrx process, Ice.Current current) { return null; } internal Ice.ObjectPrx findObject(Ice.Identity id) { lock(this) { if(id.name.Length == 0) { return null; } Ice.ObjectPrx prx = _wellKnownProxy.ice_identity(id); List adapterIds = new List(); foreach(KeyValuePair> entry in _replicaGroups) { try { prx.ice_adapterId(entry.Key).ice_ping(); adapterIds.Add(entry.Key); } catch(Ice.Exception) { } } if(adapterIds.Count == 0) { foreach(KeyValuePair entry in _adapters) { try { prx.ice_adapterId(entry.Key).ice_ping(); adapterIds.Add(entry.Key); } catch(Ice.Exception) { } } } if(adapterIds.Count == 0) { return null; } //adapterIds.Suffle(); return prx.ice_adapterId(adapterIds[0]); } } internal Ice.ObjectPrx findAdapter(string adapterId, out bool isReplicaGroup) { lock(this) { Ice.ObjectPrx result = null; if(_adapters.TryGetValue(adapterId, out result)) { isReplicaGroup = false; return result; } HashSet adapterIds; if(_replicaGroups.TryGetValue(adapterId, out adapterIds)) { List endpoints = new List(); foreach(string a in adapterIds) { Ice.ObjectPrx proxy; if(!_adapters.TryGetValue(a, out proxy)) { continue; // TODO: Inconsistency } if(result == null) { result = proxy; } endpoints.AddRange(proxy.ice_getEndpoints()); } if(result != null) { isReplicaGroup = true; return result.ice_endpoints(endpoints.ToArray()); } } isReplicaGroup = false; return null; } } private readonly Ice.ObjectPrx _wellKnownProxy; private Dictionary _adapters = new Dictionary(); private Dictionary> _replicaGroups = new Dictionary>(); }; class LocatorI : Ice.LocatorDisp_ { public LocatorI(LookupI lookup, Ice.LocatorRegistryPrx registry) { _lookup = lookup; _registry = registry; } public override Task findObjectByIdAsync(Ice.Identity id, Ice.Current current) { return _lookup.findObject(id); } public override Task findAdapterByIdAsync(string adapterId, Ice.Current current) { return _lookup.findAdapter(adapterId); } public override Ice.LocatorRegistryPrx getRegistry(Ice.Current current) { return _registry; } private LookupI _lookup; private Ice.LocatorRegistryPrx _registry; }; }