diff options
author | Marc Laukien <marc@zeroc.com> | 2006-02-28 22:55:43 +0000 |
---|---|---|
committer | Marc Laukien <marc@zeroc.com> | 2006-02-28 22:55:43 +0000 |
commit | 8db0d770f900755f66a20abedc26c8a314d730e9 (patch) | |
tree | ec6bdf2dd40e193244ab787f417f89f87a5f7391 /cpp/src | |
parent | fixing bogus config file (diff) | |
download | ice-8db0d770f900755f66a20abedc26c8a314d730e9.tar.bz2 ice-8db0d770f900755f66a20abedc26c8a314d730e9.tar.xz ice-8db0d770f900755f66a20abedc26c8a314d730e9.zip |
retry fix
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/ConnectionI.cpp | 14 | ||||
-rw-r--r-- | cpp/src/Ice/Outgoing.cpp | 31 | ||||
-rw-r--r-- | cpp/src/Ice/OutgoingAsync.cpp | 8 | ||||
-rw-r--r-- | cpp/src/Ice/Proxy.cpp | 56 | ||||
-rw-r--r-- | cpp/src/Ice/ProxyFactory.cpp | 95 | ||||
-rw-r--r-- | cpp/src/Ice/Reference.cpp | 111 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 10 |
7 files changed, 178 insertions, 147 deletions
diff --git a/cpp/src/Ice/ConnectionI.cpp b/cpp/src/Ice/ConnectionI.cpp index 593c5da9fb9..91c97d3ddc5 100644 --- a/cpp/src/Ice/ConnectionI.cpp +++ b/cpp/src/Ice/ConnectionI.cpp @@ -485,7 +485,12 @@ Ice::ConnectionI::sendRequest(BasicStream* os, Outgoing* out, bool compress) if(_exception.get()) { - _exception->ice_throw(); + // + // If the exception is closed before we even have a chance + // to send our request, we always try to send the request + // again. + // + throw LocalExceptionWrapper(*_exception.get(), true); } assert(_state > StateNotValidated); @@ -645,7 +650,12 @@ Ice::ConnectionI::sendAsyncRequest(BasicStream* os, const OutgoingAsyncPtr& out, if(_exception.get()) { - _exception->ice_throw(); + // + // If the exception is closed before we even have a chance + // to send our request, we always try to send the request + // again. + // + throw LocalExceptionWrapper(*_exception.get(), true); } assert(_state > StateNotValidated); diff --git a/cpp/src/Ice/Outgoing.cpp b/cpp/src/Ice/Outgoing.cpp index 0a081181f0a..ebe39bd4f00 100644 --- a/cpp/src/Ice/Outgoing.cpp +++ b/cpp/src/Ice/Outgoing.cpp @@ -18,23 +18,31 @@ using namespace std; using namespace Ice; using namespace IceInternal; -IceInternal::NonRepeatable::NonRepeatable(const NonRepeatable& ex) +IceInternal::LocalExceptionWrapper::LocalExceptionWrapper(const LocalException& ex, bool r) : + _retry(r) { - _ex.reset(dynamic_cast<LocalException*>(ex.get()->ice_clone())); + _ex.reset(dynamic_cast<LocalException*>(ex.ice_clone())); } -IceInternal::NonRepeatable::NonRepeatable(const ::Ice::LocalException& ex) +IceInternal::LocalExceptionWrapper::LocalExceptionWrapper(const LocalExceptionWrapper& ex) : + _retry(ex._retry) { - _ex.reset(dynamic_cast<LocalException*>(ex.ice_clone())); + _ex.reset(dynamic_cast<LocalException*>(ex.get()->ice_clone())); } -const ::Ice::LocalException* -IceInternal::NonRepeatable::get() const +const LocalException* +IceInternal::LocalExceptionWrapper::get() const { assert(_ex.get()); return _ex.get(); } +bool +IceInternal::LocalExceptionWrapper::retry() const +{ + return _retry; +} + IceInternal::Outgoing::Outgoing(ConnectionI* connection, Reference* ref, const string& operation, OperationMode mode, const Context& context, bool compress) : _connection(connection), @@ -207,11 +215,12 @@ IceInternal::Outgoing::invoke() } // - // Throw the exception wrapped in a NonRepeatable, to - // indicate that the request cannot be resent without - // potentially violating the "at-most-once" principle. + // Throw the exception wrapped in a + // LocalExceptionWrapper, to indicate that the request + // cannot be resent without potentially violating the + // "at-most-once" principle. // - throw NonRepeatable(*_exception.get()); + throw LocalExceptionWrapper(*_exception.get(), false); } if(_state == StateUserException) @@ -275,7 +284,7 @@ IceInternal::Outgoing::abort(const LocalException& ex) // only the batch request that caused the problem will be // aborted, but all other requests in the batch as well. // - throw NonRepeatable(ex); + throw LocalExceptionWrapper(ex, false); } ex.ice_throw(); diff --git a/cpp/src/Ice/OutgoingAsync.cpp b/cpp/src/Ice/OutgoingAsync.cpp index c1dcb5f3871..6145e542267 100644 --- a/cpp/src/Ice/OutgoingAsync.cpp +++ b/cpp/src/Ice/OutgoingAsync.cpp @@ -18,6 +18,7 @@ #include <Ice/LocatorInfo.h> #include <Ice/ProxyFactory.h> #include <Ice/RouterInfo.h> +#include <Ice/Outgoing.h> // For LocalExceptionWrapper. using namespace std; using namespace Ice; @@ -373,6 +374,13 @@ IceInternal::OutgoingAsync::__send() // return; } + catch(const LocalExceptionWrapper& ex) + { + if(!ex.retry()) + { + ex.get()->ice_throw(); + } + } catch(const LocalException& ex) { ProxyFactoryPtr proxyFactory = _reference->getInstance()->proxyFactory(); diff --git a/cpp/src/Ice/Proxy.cpp b/cpp/src/Ice/Proxy.cpp index b51fd80870a..f110b388dc7 100644 --- a/cpp/src/Ice/Proxy.cpp +++ b/cpp/src/Ice/Proxy.cpp @@ -163,9 +163,9 @@ IceProxy::Ice::Object::ice_isA(const string& __id, const Context& __context) Handle< ::IceDelegate::Ice::Object> __del = __getDelegate(); return __del->ice_isA(__id, __context); } - catch(const NonRepeatable& __ex) + catch(const LocalExceptionWrapper& __ex) { - __handleException(*__ex.get(), __cnt); + __handleExceptionWrapperRelaxed(__ex, __cnt); } catch(const LocalException& __ex) { @@ -192,9 +192,9 @@ IceProxy::Ice::Object::ice_ping(const Context& __context) __del->ice_ping(__context); return; } - catch(const NonRepeatable& __ex) + catch(const LocalExceptionWrapper& __ex) { - __handleException(*__ex.get(), __cnt); + __handleExceptionWrapperRelaxed(__ex, __cnt); } catch(const LocalException& __ex) { @@ -221,9 +221,9 @@ IceProxy::Ice::Object::ice_ids(const Context& __context) Handle< ::IceDelegate::Ice::Object> __del = __getDelegate(); return __del->ice_ids(__context); } - catch(const NonRepeatable& __ex) + catch(const LocalExceptionWrapper& __ex) { - __handleException(*__ex.get(), __cnt); + __handleExceptionWrapperRelaxed(__ex, __cnt); } catch(const LocalException& __ex) { @@ -250,9 +250,9 @@ IceProxy::Ice::Object::ice_id(const Context& __context) Handle< ::IceDelegate::Ice::Object> __del = __getDelegate(); return __del->ice_id(__context); } - catch(const NonRepeatable& __ex) + catch(const LocalExceptionWrapper& __ex) { - __handleException(*__ex.get(), __cnt); + __handleExceptionWrapperRelaxed(__ex, __cnt); } catch(const LocalException& __ex) { @@ -285,16 +285,16 @@ IceProxy::Ice::Object::ice_invoke(const string& operation, Handle< ::IceDelegate::Ice::Object> __del = __getDelegate(); return __del->ice_invoke(operation, mode, inParams, outParams, context); } - catch(const NonRepeatable& __ex) + catch(const LocalExceptionWrapper& __ex) { bool canRetry = mode == Nonmutating || mode == Idempotent; if(canRetry) { - __handleException(*__ex.get(), __cnt); + __handleExceptionWrapperRelaxed(__ex, __cnt); } else { - __rethrowException(*__ex.get()); + __handleExceptionWrapper(__ex); } } catch(const LocalException& __ex) @@ -818,17 +818,31 @@ IceProxy::Ice::Object::__handleException(const LocalException& ex, int& cnt) } void -IceProxy::Ice::Object::__rethrowException(const LocalException& ex) +IceProxy::Ice::Object::__handleExceptionWrapper(const LocalExceptionWrapper& ex) { - // - // Only _delegate needs to be mutex protected here. - // { IceUtil::Mutex::Lock sync(*this); _delegate = 0; } - ex.ice_throw(); + if(!ex.retry()) + { + ex.get()->ice_throw(); + } +} + +void +IceProxy::Ice::Object::__handleExceptionWrapperRelaxed(const LocalExceptionWrapper& ex, int& cnt) +{ + if(!ex.retry()) + { + __handleException(*ex.get(), cnt); + } + else + { + IceUtil::Mutex::Lock sync(*this); + _delegate = 0; + } } // @@ -993,7 +1007,7 @@ IceDelegateM::Ice::Object::ice_isA(const string& __id, const Context& __context) } catch(const ::Ice::LocalException& __ex) { - throw ::IceInternal::NonRepeatable(__ex); + throw ::IceInternal::LocalExceptionWrapper(__ex, false); } return __ret; } @@ -1021,7 +1035,7 @@ IceDelegateM::Ice::Object::ice_ping(const Context& __context) } catch(const ::Ice::LocalException& __ex) { - throw ::IceInternal::NonRepeatable(__ex); + throw ::IceInternal::LocalExceptionWrapper(__ex, false); } } @@ -1050,7 +1064,7 @@ IceDelegateM::Ice::Object::ice_ids(const Context& __context) } catch(const ::Ice::LocalException& __ex) { - throw ::IceInternal::NonRepeatable(__ex); + throw ::IceInternal::LocalExceptionWrapper(__ex, false); } return __ret; } @@ -1080,7 +1094,7 @@ IceDelegateM::Ice::Object::ice_id(const Context& __context) } catch(const ::Ice::LocalException& __ex) { - throw ::IceInternal::NonRepeatable(__ex); + throw ::IceInternal::LocalExceptionWrapper(__ex, false); } return __ret; } @@ -1113,7 +1127,7 @@ IceDelegateM::Ice::Object::ice_invoke(const string& operation, } catch(const ::Ice::LocalException& __ex) { - throw ::IceInternal::NonRepeatable(__ex); + throw ::IceInternal::LocalExceptionWrapper(__ex, false); } } return ok; diff --git a/cpp/src/Ice/ProxyFactory.cpp b/cpp/src/Ice/ProxyFactory.cpp index 0666f4b2777..b9352ae41c9 100644 --- a/cpp/src/Ice/ProxyFactory.cpp +++ b/cpp/src/Ice/ProxyFactory.cpp @@ -111,24 +111,25 @@ IceInternal::ProxyFactory::checkRetryAfterException(const LocalException& ex, co // // There is no point in retrying an operation that resulted in a - // MarshalException. This must have been raised locally (because if - // it happened in a server it would result in an UnknownLocalException - // instead), which means there was a problem in this process that will - // not change if we try again. + // MarshalException. This must have been raised locally (because + // if it happened in a server it would result in an + // UnknownLocalException instead), which means there was a problem + // in this process that will not change if we try again. // // The most likely cause for a MarshalException is exceeding the // maximum message size, which is represented by the the subclass - // MemoryLimitException. For example, a client can attempt to send a - // message that exceeds the maximum memory size, or accumulate enough - // batch requests without flushing that the maximum size is reached. + // MemoryLimitException. For example, a client can attempt to send + // a message that exceeds the maximum memory size, or accumulate + // enough batch requests without flushing that the maximum size is + // reached. // - // This latter case is especially problematic, because if we were to - // retry a batch request after a MarshalException, we would in fact - // silently discard the accumulated requests and allow new batch - // requests to accumulate. If the subsequent batched requests do not - // exceed the maximum message size, it appears to the client that all - // of the batched requests were accepted, when in reality only the - // last few are actually sent. + // This latter case is especially problematic, because if we were + // to retry a batch request after a MarshalException, we would in + // fact silently discard the accumulated requests and allow new + // batch requests to accumulate. If the subsequent batched + // requests do not exceed the maximum message size, it appears to + // the client that all of the batched requests were accepted, when + // in reality only the last few are actually sent. // if(dynamic_cast<const MarshalException*>(&ex)) { @@ -136,52 +137,40 @@ IceInternal::ProxyFactory::checkRetryAfterException(const LocalException& ex, co } ++cnt; + assert(cnt > 0); TraceLevelsPtr traceLevels = _instance->traceLevels(); LoggerPtr logger = _instance->logger(); - // - // Instance components may be null if the communicator has been - // destroyed. - // - if(traceLevels && logger) + if(cnt > static_cast<int>(_retryIntervals.size())) { - if(cnt > static_cast<int>(_retryIntervals.size())) - { - if(traceLevels->retry >= 1) - { - Trace out(logger, traceLevels->retryCat); - out << "cannot retry operation call because retry limit has been exceeded\n" << ex; - } - ex.ice_throw(); - } - - if(traceLevels->retry >= 1) - { - Trace out(logger, traceLevels->retryCat); - out << "re-trying operation call"; - if(cnt > 0 && _retryIntervals[cnt - 1] > 0) - { - out << " in " << _retryIntervals[cnt - 1] << "ms"; - } - out << " because of exception\n" << ex; - } - - if(cnt > 0) - { - // - // Sleep before retrying. - // - IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(_retryIntervals[cnt - 1])); - } + if(traceLevels->retry >= 1) + { + Trace out(logger, traceLevels->retryCat); + out << "cannot retry operation call because retry limit has been exceeded\n" << ex; + } + ex.ice_throw(); } - else + + int interval = _retryIntervals[cnt - 1]; + + if(traceLevels->retry >= 1) { - // - // Impossible to retry after the communicator has been - // destroyed. - // - ex.ice_throw(); + Trace out(logger, traceLevels->retryCat); + out << "re-trying operation call"; + if(interval > 0) + { + out << " in " << interval << "ms"; + } + out << " because of exception\n" << ex; + } + + if(interval > 0) + { + // + // Sleep before retrying. + // + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(interval)); } } diff --git a/cpp/src/Ice/Reference.cpp b/cpp/src/Ice/Reference.cpp index 0a84aced76c..1d0d1d410af 100644 --- a/cpp/src/Ice/Reference.cpp +++ b/cpp/src/Ice/Reference.cpp @@ -408,29 +408,29 @@ public: }; IceInternal::Reference::Reference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, - const Context& ctx, const string& fs, Mode md) - : _instance(inst), - _communicator(com), - _mode(md), - _identity(ident), - _context(ctx), - _facet(fs), - _cacheConnection(true), - _endpointSelection(Random), - _hashInitialized(false) + const Context& ctx, const string& fs, Mode md) : + _hashInitialized(false), + _instance(inst), + _communicator(com), + _mode(md), + _identity(ident), + _context(ctx), + _facet(fs), + _cacheConnection(true), + _endpointSelection(Random) { } -IceInternal::Reference::Reference(const Reference& r) - : _instance(r._instance), - _communicator(r._communicator), - _mode(r._mode), - _identity(r._identity), - _context(r._context), - _facet(r._facet), - _cacheConnection(r._cacheConnection), - _endpointSelection(r._endpointSelection), - _hashInitialized(false) +IceInternal::Reference::Reference(const Reference& r) : + _hashInitialized(false), + _instance(r._instance), + _communicator(r._communicator), + _mode(r._mode), + _identity(r._identity), + _context(r._context), + _facet(r._facet), + _cacheConnection(r._cacheConnection), + _endpointSelection(r._endpointSelection) { } @@ -439,9 +439,9 @@ void IceInternal::decRef(IceInternal::FixedReference* p) { p->__decRef(); } IceInternal::FixedReference::FixedReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, - const vector<ConnectionIPtr>& fixedConns) - : Reference(inst, com, ident, ctx, fs, md), - _fixedConnections(fixedConns) + const vector<ConnectionIPtr>& fixedConns) : + Reference(inst, com, ident, ctx, fs, md), + _fixedConnections(fixedConns) { } @@ -626,9 +626,9 @@ IceInternal::FixedReference::clone() const return new FixedReference(*this); } -IceInternal::FixedReference::FixedReference(const FixedReference& r) - : Reference(r), - _fixedConnections(r._fixedConnections) +IceInternal::FixedReference::FixedReference(const FixedReference& r) : + Reference(r), + _fixedConnections(r._fixedConnections) { } @@ -834,19 +834,19 @@ IceInternal::RoutableReference::operator<(const Reference& r) const IceInternal::RoutableReference::RoutableReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, - bool sec, const RouterInfoPtr& rtrInfo, bool collocationOpt) - : Reference(inst, com, ident, ctx, fs, md), - _secure(sec), - _routerInfo(rtrInfo), - _collocationOptimization(collocationOpt) + bool sec, const RouterInfoPtr& rtrInfo, bool collocationOpt) : + Reference(inst, com, ident, ctx, fs, md), + _secure(sec), + _routerInfo(rtrInfo), + _collocationOptimization(collocationOpt) { } -IceInternal::RoutableReference::RoutableReference(const RoutableReference& r) - : Reference(r), - _secure(r._secure), - _routerInfo(r._routerInfo), - _collocationOptimization(r._collocationOptimization) +IceInternal::RoutableReference::RoutableReference(const RoutableReference& r) : + Reference(r), + _secure(r._secure), + _routerInfo(r._routerInfo), + _collocationOptimization(r._collocationOptimization) { } @@ -992,9 +992,9 @@ void IceInternal::decRef(IceInternal::DirectReference* p) { p->__decRef(); } IceInternal::DirectReference::DirectReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, bool sec, const vector<EndpointIPtr>& endpts, - const RouterInfoPtr& rtrInfo, bool collocationOpt) - : RoutableReference(inst, com, ident, ctx, fs, md, sec, rtrInfo, collocationOpt), - _endpoints(endpts) + const RouterInfoPtr& rtrInfo, bool collocationOpt) : + RoutableReference(inst, com, ident, ctx, fs, md, sec, rtrInfo, collocationOpt), + _endpoints(endpts) { } @@ -1223,9 +1223,9 @@ IceInternal::DirectReference::clone() const return new DirectReference(*this); } -IceInternal::DirectReference::DirectReference(const DirectReference& r) - : RoutableReference(r), - _endpoints(r._endpoints) +IceInternal::DirectReference::DirectReference(const DirectReference& r) : + RoutableReference(r), + _endpoints(r._endpoints) { } @@ -1236,11 +1236,11 @@ IceInternal::IndirectReference::IndirectReference(const InstancePtr& inst, const const Identity& ident, const Context& ctx, const string& fs, Mode md, bool sec, const string& adptid, const RouterInfoPtr& rtrInfo, const LocatorInfoPtr& locInfo, bool collocationOpt, - int locatorCacheTimeout) - : RoutableReference(inst, com, ident, ctx, fs, md, sec, rtrInfo, collocationOpt), - _adapterId(adptid), - _locatorInfo(locInfo), - _locatorCacheTimeout(locatorCacheTimeout) + int locatorCacheTimeout) : + RoutableReference(inst, com, ident, ctx, fs, md, sec, rtrInfo, collocationOpt), + _adapterId(adptid), + _locatorInfo(locInfo), + _locatorCacheTimeout(locatorCacheTimeout) { } @@ -1485,7 +1485,9 @@ IceInternal::IndirectReference::hash() const return _hashValue; } RoutableReference::hash(); // Initializes _hashValue. - for(string::const_iterator p = _adapterId.begin(); p != _adapterId.end(); ++p) // Add hash of adapter ID to base hash. + + // Add hash of adapter ID to base hash. + for(string::const_iterator p = _adapterId.begin(); p != _adapterId.end(); ++p) { _hashValue = 5 * _hashValue + *p; } @@ -1570,12 +1572,11 @@ IceInternal::IndirectReference::clone() const return new IndirectReference(*this); } -IceInternal::IndirectReference::IndirectReference(const IndirectReference& r) - : RoutableReference(r), - _adapterId(r._adapterId), - _connectionId(r._connectionId), - _locatorInfo(r._locatorInfo), - _locatorCacheTimeout(r._locatorCacheTimeout) +IceInternal::IndirectReference::IndirectReference(const IndirectReference& r) : + RoutableReference(r), + _adapterId(r._adapterId), + _connectionId(r._connectionId), + _locatorInfo(r._locatorInfo), + _locatorCacheTimeout(r._locatorCacheTimeout) { } - diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 96e87b88255..ddd70a20380 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -1767,15 +1767,15 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) C << nl << "return;"; } C << eb; - C << nl << "catch(const ::IceInternal::NonRepeatable& __ex)"; + C << nl << "catch(const ::IceInternal::LocalExceptionWrapper& __ex)"; C << sb; if(p->mode() == Operation::Idempotent || p->mode() == Operation::Nonmutating) { - C << nl << "__handleException(*__ex.get(), __cnt);"; + C << nl << "__handleExceptionWrapperRelaxed(__ex, __cnt);"; } else { - C << nl << "__rethrowException(*__ex.get());"; + C << nl << "__handleExceptionWrapper(__ex);"; } C << eb; C << nl << "catch(const ::Ice::LocalException& __ex)"; @@ -2165,7 +2165,7 @@ Slice::Gen::DelegateMVisitor::visitOperation(const OperationPtr& p) C << eb; C << nl << "catch(const ::Ice::LocalException& __ex)"; C << sb; - C << nl << "throw ::IceInternal::NonRepeatable(__ex);"; + C << nl << "throw ::IceInternal::LocalExceptionWrapper(__ex, false);"; C << eb; C << eb; } @@ -2360,7 +2360,7 @@ Slice::Gen::DelegateDVisitor::visitOperation(const OperationPtr& p) C << eb; C << nl << "catch(const ::Ice::LocalException& __ex)"; C << sb; - C << nl << "throw ::IceInternal::NonRepeatable(__ex);"; + C << nl << "throw ::IceInternal::LocalExceptionWrapper(__ex, false);"; C << eb; C << eb; C << eb; |