From f0fbb296946f95b2bd94e86d72df618aadf3268c Mon Sep 17 00:00:00 2001 From: Benoit Foucher Date: Wed, 10 May 2017 18:54:03 +0200 Subject: Fixed ICE-7849 - Removed IceDiscovery/IceLocatorDiscovery ice_getConnection call, added IceGrid/simple C++11 test --- csharp/src/Ice/Network.cs | 2 +- csharp/src/IceDiscovery/LookupI.cs | 194 +++++++++++++++++++++--------- csharp/src/IceLocatorDiscovery/PluginI.cs | 105 ++++++++++------ 3 files changed, 206 insertions(+), 95 deletions(-) (limited to 'csharp/src') diff --git a/csharp/src/Ice/Network.cs b/csharp/src/Ice/Network.cs index 7606f6f4a98..08ffc80a77b 100644 --- a/csharp/src/Ice/Network.cs +++ b/csharp/src/Ice/Network.cs @@ -445,7 +445,7 @@ namespace IceInternal socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface, ifaceIndex); } } - catch(SocketException ex) + catch(Exception ex) { closeSocketNoThrow(socket); throw new Ice.SocketException(ex); diff --git a/csharp/src/IceDiscovery/LookupI.cs b/csharp/src/IceDiscovery/LookupI.cs index 9c4abb2d8a1..1912505f2da 100644 --- a/csharp/src/IceDiscovery/LookupI.cs +++ b/csharp/src/IceDiscovery/LookupI.cs @@ -15,12 +15,12 @@ namespace IceDiscovery using System.Text; using System.Diagnostics; - class Request + abstract class Request { protected Request(LookupI lookup, T id, int retryCount) { lookup_ = lookup; - nRetry_ = retryCount; + retryCount_ = retryCount; _id = id; } @@ -37,14 +37,40 @@ namespace IceDiscovery public virtual bool retry() { - return --nRetry_ >= 0; + return --retryCount_ >= 0; } + public void invoke(String domainId, Dictionary lookups) + { + _lookupCount = lookups.Count; + _failureCount = 0; + foreach(var entry in lookups) + { + invokeWithLookup(domainId, entry.Key, entry.Value); + } + } + + public bool exception() + { + if(++_failureCount == _lookupCount) + { + finished(null); + return true; + } + return false; + } + + abstract public void finished(Ice.ObjectPrx proxy); + + abstract protected void invokeWithLookup(string domainId, LookupPrx lookup, LookupReplyPrx lookupReply); + protected LookupI lookup_; - protected int nRetry_; + protected int retryCount_; + protected int _lookupCount; + protected int _failureCount; protected List> callbacks_ = new List>(); - private T _id; + protected T _id; }; class AdapterRequest : Request, IceInternal.TimerTask @@ -56,7 +82,7 @@ namespace IceDiscovery public override bool retry() { - return _proxies.Count == 0 && --nRetry_ >= 0; + return _proxies.Count == 0 && --retryCount_ >= 0; } public bool response(Ice.ObjectPrx proxy, bool isReplicaGroup) @@ -80,7 +106,7 @@ namespace IceDiscovery return true; } - public void finished(Ice.ObjectPrx proxy) + public override void finished(Ice.ObjectPrx proxy) { if(proxy != null || _proxies.Count == 0) { @@ -111,6 +137,20 @@ namespace IceDiscovery lookup_.adapterRequestTimedOut(this); } + protected override void invokeWithLookup(string domainId, LookupPrx lookup, LookupReplyPrx lookupReply) + { + lookup.findAdapterByIdAsync(domainId, _id, lookupReply).ContinueWith(task => { + try + { + task.Wait(); + } + catch(AggregateException ex) + { + lookup_.adapterRequestException(this, ex.InnerException); + } + }); + } + private void sendResponse(Ice.ObjectPrx proxy) { foreach(var cb in callbacks_) @@ -136,7 +176,7 @@ namespace IceDiscovery finished(proxy); } - public void finished(Ice.ObjectPrx proxy) + public override void finished(Ice.ObjectPrx proxy) { foreach(var cb in callbacks_) { @@ -149,6 +189,20 @@ namespace IceDiscovery { lookup_.objectRequestTimedOut(this); } + + protected override void invokeWithLookup(string domainId, LookupPrx lookup, LookupReplyPrx lookupReply) + { + lookup.findObjectByIdAsync(domainId, _id, lookupReply).ContinueWith(task => { + try + { + task.Wait(); + } + catch(AggregateException ex) + { + lookup_.objectRequestException(this, ex.InnerException); + } + }); + } }; class LookupI : LookupDisp_ @@ -156,27 +210,13 @@ namespace IceDiscovery public LookupI(LocatorRegistryI registry, LookupPrx lookup, Ice.Properties properties) { _registry = registry; + _lookup = lookup; _timeout = properties.getPropertyAsIntWithDefault("IceDiscovery.Timeout", 300); _retryCount = properties.getPropertyAsIntWithDefault("IceDiscovery.RetryCount", 3); _latencyMultiplier = properties.getPropertyAsIntWithDefault("IceDiscovery.LatencyMultiplier", 1); _domainId = properties.getProperty("IceDiscovery.DomainId"); _timer = IceInternal.Util.getInstance(lookup.ice_getCommunicator()).timer(); - try - { - lookup.ice_getConnection(); - } - catch(Ice.LocalException ex) - { - StringBuilder b = new StringBuilder(); - b.Append("IceDiscovery is unable to establish a multicast connection:\n"); - b.Append("proxy = "); - b.Append(lookup.ToString()); - b.Append('\n'); - b.Append(ex.ToString()); - throw new Ice.PluginInitializationException(b.ToString()); - } - // // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast // datagram on each endpoint. @@ -184,19 +224,10 @@ namespace IceDiscovery var single = new Ice.Endpoint[1]; foreach(var endpt in lookup.ice_getEndpoints()) { - try - { - single[0] = endpt; - LookupPrx l = (LookupPrx)lookup.ice_endpoints(single); - l.ice_getConnection(); - _lookup[(LookupPrx)lookup.ice_endpoints(single)] = null; - } - catch(Ice.LocalException) - { - // Ignore - } + single[0] = endpt; + _lookups[(LookupPrx)lookup.ice_endpoints(single)] = null; } - Debug.Assert(_lookup.Count > 0); + Debug.Assert(_lookups.Count > 0); } public void setLookupReply(LookupReplyPrx lookupReply) @@ -205,7 +236,7 @@ namespace IceDiscovery // Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams. // var single = new Ice.Endpoint[1]; - foreach(var key in new List(_lookup.Keys)) + foreach(var key in new List(_lookups.Keys)) { var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo(); if(info.mcastInterface.Length > 0) @@ -216,15 +247,15 @@ namespace IceDiscovery if(r is Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface)) { single[0] = q; - _lookup[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single); + _lookups[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single); } } } - if(_lookup[key] == null) + if(_lookups[key] == null) { // Fallback: just use the given lookup reply proxy if no matching endpoint found. - _lookup[key] = lookupReply; + _lookups[key] = lookupReply; } } } @@ -296,10 +327,7 @@ namespace IceDiscovery { try { - foreach(var l in _lookup) - { - l.Key.findObjectByIdAsync(_domainId, id, l.Value); - } + request.invoke(_domainId, _lookups); _timer.schedule(request, _timeout); } catch(Ice.LocalException) @@ -328,10 +356,7 @@ namespace IceDiscovery { try { - foreach(var l in _lookup) - { - l.Key.findAdapterByIdAsync(_domainId, adapterId, l.Value); - } + request.invoke(_domainId, _lookups); _timer.schedule(request, _timeout); } catch(Ice.LocalException) @@ -391,10 +416,7 @@ namespace IceDiscovery { try { - foreach(var l in _lookup) - { - l.Key.findObjectByIdAsync(_domainId, request.getId(), l.Value); - } + request.invoke(_domainId, _lookups); _timer.schedule(request, _timeout); return; } @@ -409,6 +431,36 @@ namespace IceDiscovery } } + internal void objectRequestException(ObjectRequest request, Exception ex) + { + lock(this) + { + ObjectRequest r; + if(!_objectRequests.TryGetValue(request.getId(), out r) || r != request) + { + return; + } + + if(request.exception()) + { + if(_warnOnce) + { + StringBuilder s = new StringBuilder(); + s.Append("failed to lookup object `"); + s.Append(_lookup.ice_getCommunicator().identityToString(request.getId())); + s.Append("' with lookup proxy `"); + s.Append(_lookup); + s.Append("':\n"); + s.Append(ex.ToString()); + _lookup.ice_getCommunicator().getLogger().warning(s.ToString()); + _warnOnce = false; + } + _timer.cancel(request); + _objectRequests.Remove(request.getId()); + } + } + } + internal void adapterRequestTimedOut(AdapterRequest request) { lock(this) @@ -423,10 +475,7 @@ namespace IceDiscovery { try { - foreach(var l in _lookup) - { - l.Key.findAdapterByIdAsync(_domainId, request.getId(), l.Value); - } + request.invoke(_domainId, _lookups); _timer.schedule(request, _timeout); return; } @@ -441,6 +490,36 @@ namespace IceDiscovery } } + internal void adapterRequestException(AdapterRequest request, Exception ex) + { + lock(this) + { + AdapterRequest r; + if(!_adapterRequests.TryGetValue(request.getId(), out r) || r != request) + { + return; + } + + if(request.exception()) + { + if(_warnOnce) + { + StringBuilder s = new StringBuilder(); + s.Append("failed to lookup adapter `"); + s.Append(request.getId()); + s.Append("' with lookup proxy `"); + s.Append(_lookup); + s.Append("':\n"); + s.Append(ex.ToString()); + _lookup.ice_getCommunicator().getLogger().warning(s.ToString()); + _warnOnce = false; + } + _timer.cancel(request); + _adapterRequests.Remove(request.getId()); + } + } + } + internal IceInternal.Timer timer() { return _timer; @@ -452,14 +531,15 @@ namespace IceDiscovery } private LocatorRegistryI _registry; - private Dictionary _lookup = new Dictionary(); + private LookupPrx _lookup; + private Dictionary _lookups = new Dictionary(); private readonly int _timeout; private readonly int _retryCount; private readonly int _latencyMultiplier; private readonly string _domainId; private IceInternal.Timer _timer; - + private bool _warnOnce = true; private Dictionary _objectRequests = new Dictionary(); private Dictionary _adapterRequests = new Dictionary(); }; diff --git a/csharp/src/IceLocatorDiscovery/PluginI.cs b/csharp/src/IceLocatorDiscovery/PluginI.cs index 2a55fe8d4cc..0a91aec1c41 100644 --- a/csharp/src/IceLocatorDiscovery/PluginI.cs +++ b/csharp/src/IceLocatorDiscovery/PluginI.cs @@ -142,6 +142,7 @@ namespace IceLocatorDiscovery LocatorI(string name, LookupPrx lookup, Ice.Properties properties, string instanceName, Ice.LocatorPrx voidLocator) { + _lookup = lookup; _timeout = properties.getPropertyAsIntWithDefault(name + ".Timeout", 300); _retryCount = properties.getPropertyAsIntWithDefault(name + ".RetryCount", 3); _retryDelay = properties.getPropertyAsIntWithDefault(name + ".RetryDelay", 2000); @@ -151,21 +152,8 @@ namespace IceLocatorDiscovery _locator = lookup.ice_getCommunicator().getDefaultLocator(); _voidLocator = voidLocator; _pendingRetryCount = 0; - - try - { - lookup.ice_getConnection(); - } - catch(Ice.LocalException ex) - { - StringBuilder b = new StringBuilder(); - b.Append("IceLocatorDiscovery is unable to establish a multicast connection:\n"); - b.Append("proxy = "); - b.Append(lookup.ToString()); - b.Append('\n'); - b.Append(ex.ToString()); - throw new Ice.PluginInitializationException(b.ToString()); - } + _failureCount = 0; + _warnOnce = true; // // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast @@ -174,19 +162,10 @@ namespace IceLocatorDiscovery var single = new Ice.Endpoint[1]; foreach(var endpt in lookup.ice_getEndpoints()) { - try - { - single[0] = endpt; - LookupPrx l = (LookupPrx)lookup.ice_endpoints(single); - l.ice_getConnection(); - _lookup[(LookupPrx)lookup.ice_endpoints(single)] = null; - } - catch(Ice.LocalException) - { - // Ignore - } + single[0] = endpt; + _lookups[(LookupPrx)lookup.ice_endpoints(single)] = null; } - Debug.Assert(_lookup.Count > 0); + Debug.Assert(_lookups.Count > 0); } public void @@ -196,7 +175,7 @@ namespace IceLocatorDiscovery // Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams. // var single = new Ice.Endpoint[1]; - foreach(var key in new List(_lookup.Keys)) + foreach(var key in new List(_lookups.Keys)) { var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo(); if(info.mcastInterface.Length > 0) @@ -207,15 +186,15 @@ namespace IceLocatorDiscovery if(r is Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface)) { single[0] = q; - _lookup[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single); + _lookups[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single); } } } - if(_lookup[key] == null) + if(_lookups[key] == null) { // Fallback: just use the given lookup reply proxy if no matching endpoint found. - _lookup[key] = lookupReply; + _lookups[key] = lookupReply; } } } @@ -406,11 +385,21 @@ namespace IceLocatorDiscovery if(_pendingRetryCount == 0) // No request in progress { _pendingRetryCount = _retryCount; + _failureCount = 0; try { - foreach(var l in _lookup) + foreach(var l in _lookups) { - l.Key.findLocatorAsync(_instanceName, l.Value); // Send multicast request. + l.Key.findLocatorAsync(_instanceName, l.Value).ContinueWith(t => { + try + { + t.Wait(); + } + catch(AggregateException ex) + { + exception(ex.InnerException); + } + }); // Send multicast request. } _timer.schedule(this, _timeout); } @@ -428,8 +417,47 @@ namespace IceLocatorDiscovery } } - public void - runTimerTask() + void exception(Exception ex) + { + lock(this) + { + if(++_failureCount == _lookups.Count && _pendingRetryCount > 0) + { + // + // All the lookup calls failed, cancel the timer and propagate the error to the requests. + // + _timer.cancel(this); + + _pendingRetryCount = 0; + + if(_warnOnce) + { + StringBuilder builder = new StringBuilder(); + builder.Append("failed to lookup locator with lookup proxy `"); + builder.Append(_lookup); + builder.Append("':\n"); + builder.Append(ex); + _lookup.ice_getCommunicator().getLogger().warning(builder.ToString()); + _warnOnce = false; + } + + if(_pendingRequests.Count == 0) + { + Monitor.Pulse(this); + } + else + { + foreach(Request req in _pendingRequests) + { + req.invoke(_voidLocator); + } + _pendingRequests.Clear(); + } + } + } + } + + public void runTimerTask() { lock(this) { @@ -437,7 +465,7 @@ namespace IceLocatorDiscovery { try { - foreach(var l in _lookup) + foreach(var l in _lookups) { l.Key.findLocatorAsync(_instanceName, l.Value); // Send multicast request } @@ -459,7 +487,8 @@ namespace IceLocatorDiscovery } } - private Dictionary _lookup = new Dictionary(); + private LookupPrx _lookup; + private Dictionary _lookups = new Dictionary(); private int _timeout; private IceInternal.Timer _timer; private int _retryCount; @@ -472,6 +501,8 @@ namespace IceLocatorDiscovery private Dictionary _locators = new Dictionary(); private int _pendingRetryCount; + private int _failureCount; + private bool _warnOnce = true; private List _pendingRequests = new List(); private long _nextRetry; }; -- cgit v1.2.3