diff options
Diffstat (limited to 'java/src/IceInternal/LocatorInfo.java')
-rw-r--r-- | java/src/IceInternal/LocatorInfo.java | 802 |
1 files changed, 489 insertions, 313 deletions
diff --git a/java/src/IceInternal/LocatorInfo.java b/java/src/IceInternal/LocatorInfo.java index 40c59bbd946..bcf28e5865d 100644 --- a/java/src/IceInternal/LocatorInfo.java +++ b/java/src/IceInternal/LocatorInfo.java @@ -1,6 +1,6 @@ // ********************************************************************** // -// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// Copyright (c) 2003-2009 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. @@ -17,10 +17,318 @@ public final class LocatorInfo void setException(Ice.LocalException ex); } - LocatorInfo(Ice.LocatorPrx locator, LocatorTable table) + private class RequestCallback + { + public void + response(LocatorInfo locatorInfo, Ice.ObjectPrx proxy) + { + EndpointI[] endpoints = null; + if(proxy != null) + { + Reference r = ((Ice.ObjectPrxHelperBase)proxy).__reference(); + if(!r.isIndirect()) + { + endpoints = r.getEndpoints(); + } + else if(_ref.isWellKnown() && !r.isWellKnown()) + { + // + // We're resolving the endpoints of a well-known object and the proxy returned + // by the locator is an indirect proxy. We now need to resolve the endpoints + // of this indirect proxy. + // + locatorInfo.getEndpoints(r, _ref, _ttl, _callback); + return; + } + } + + if(_ref.getInstance().traceLevels().location >= 1) + { + locatorInfo.getEndpointsTrace(_ref, endpoints, false); + } + if(_callback != null) + { + _callback.setEndpoints(endpoints == null ? new EndpointI[0] : endpoints, false); + } + } + + public void + exception(LocatorInfo locatorInfo, Exception exc) + { + try + { + locatorInfo.getEndpointsException(_ref, exc); // This throws. + } + catch(Ice.LocalException ex) + { + if(_callback != null) + { + _callback.setException(ex); + } + } + } + + RequestCallback(Reference ref, int ttl, GetEndpointsCallback cb) + { + _ref = ref; + _ttl = ttl; + _callback = cb; + } + + final Reference _ref; + final int _ttl; + final GetEndpointsCallback _callback; + }; + + private abstract class Request + { + synchronized public void + addCallback(Reference ref, Reference wellKnownRef, int ttl, GetEndpointsCallback cb) + { + RequestCallback callback = new RequestCallback(ref, ttl, cb); + if(_response) + { + callback.response(_locatorInfo, _proxy); + } + else if(_exception != null) + { + callback.exception(_locatorInfo, _exception); + } + else + { + _callbacks.add(callback); + if(wellKnownRef != null) // This request is to resolve the endpoints of a cached well-known object ref + { + _wellKnownRefs.add(wellKnownRef); + } + if(!_sent) + { + _sent = true; + send(true); + } + } + } + + synchronized EndpointI[] + getEndpoints(Reference ref, Reference wellKnownRef, int ttl, Ice.BooleanHolder cached) + { + if(!_response || _exception == null) + { + if(wellKnownRef != null) // This request is to resolve the endpoints of a cached well-known object ref + { + _wellKnownRefs.add(wellKnownRef); + } + if(!_sent) + { + _sent = true; + send(true); + } + + while(!_response && _exception == null) + { + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + } + + if(_exception != null) + { + _locatorInfo.getEndpointsException(ref, _exception); // This throws. + } + + assert(_response); + EndpointI[] endpoints = null; + if(_proxy != null) + { + Reference r = ((Ice.ObjectPrxHelperBase)_proxy).__reference(); + if(!r.isIndirect()) + { + endpoints = r.getEndpoints(); + } + else if(ref.isWellKnown() && !r.isWellKnown()) + { + // + // We're resolving the endpoints of a well-known object and the proxy returned + // by the locator is an indirect proxy. We now need to resolve the endpoints + // of this indirect proxy. + // + return _locatorInfo.getEndpoints(r, ref, ttl, cached); + } + } + + cached.value = false; + if(_ref.getInstance().traceLevels().location >= 1) + { + _locatorInfo.getEndpointsTrace(ref, endpoints, false); + } + return endpoints == null ? new EndpointI[0] : endpoints; + } + + Request(LocatorInfo locatorInfo, Reference ref) + { + _locatorInfo = locatorInfo; + _ref = ref; + _sent = false; + _response = false; + } + + synchronized protected void + response(Ice.ObjectPrx proxy) + { + _locatorInfo.finishRequest(_ref, _wellKnownRefs, proxy, false); + _response = true; + _proxy = proxy; + for(RequestCallback callback : _callbacks) + { + callback.response(_locatorInfo, proxy); + } + notifyAll(); + } + + protected void + exception(Exception ex) + { + if(ex instanceof Ice.CollocationOptimizationException) + { + send(false); // Use synchronous collocation optimized locator request instead. + return; + } + + synchronized(this) + { + _locatorInfo.finishRequest(_ref, _wellKnownRefs, null, ex instanceof Ice.UserException); + _exception = ex; + for(RequestCallback callback : _callbacks) + { + callback.exception(_locatorInfo, ex); + } + notifyAll(); + } + } + + protected abstract void send(boolean async); + + final protected LocatorInfo _locatorInfo; + final protected Reference _ref; + + private java.util.List<RequestCallback> _callbacks = new java.util.ArrayList<RequestCallback>(); + private java.util.List<Reference> _wellKnownRefs = new java.util.ArrayList<Reference>(); + private boolean _sent; + private boolean _response; + private Ice.ObjectPrx _proxy; + private Exception _exception; + }; + + private class ObjectRequest extends Request + { + public ObjectRequest(LocatorInfo locatorInfo, Reference reference) + { + super(locatorInfo, reference); + assert(reference.isWellKnown()); + } + + protected void + send(boolean async) + { + try + { + if(async) + { + _locatorInfo.getLocator().findObjectById_async( + new Ice.AMI_Locator_findObjectById() + { + public void + ice_response(Ice.ObjectPrx proxy) + { + response(proxy); + } + + public void + ice_exception(Ice.UserException ex) + { + exception(ex); + } + + public void + ice_exception(Ice.LocalException ex) + { + exception(ex); + } + }, + _ref.getIdentity()); + } + else + { + response(_locatorInfo.getLocator().findObjectById(_ref.getIdentity())); + } + } + catch(Exception ex) + { + exception(ex); + } + } + }; + + private class AdapterRequest extends Request + { + public AdapterRequest(LocatorInfo locatorInfo, Reference reference) + { + super(locatorInfo, reference); + assert(reference.isIndirect()); + } + + protected void + send(boolean async) + { + try + { + if(async) + { + _locatorInfo.getLocator().findAdapterById_async( + new Ice.AMI_Locator_findAdapterById() + { + public void + ice_response(Ice.ObjectPrx proxy) + { + response(proxy); + } + + public void + ice_exception(Ice.UserException ex) + { + exception(ex); + } + + public void + ice_exception(Ice.LocalException ex) + { + exception(ex); + } + }, + _ref.getAdapterId()); + } + else + { + response(_locatorInfo.getLocator().findAdapterById(_ref.getAdapterId())); + } + } + catch(Exception ex) + { + exception(ex); + } + } + }; + + LocatorInfo(Ice.LocatorPrx locator, LocatorTable table, boolean background) { _locator = locator; _table = table; + _background = background; } synchronized public void @@ -74,281 +382,130 @@ public final class LocatorInfo public EndpointI[] getEndpoints(Reference ref, int ttl, Ice.BooleanHolder cached) { - assert(ref.isIndirect()); + return getEndpoints(ref, null, ttl, cached); + } + public EndpointI[] + getEndpoints(Reference ref, Reference wellKnownRef, int ttl, Ice.BooleanHolder cached) + { + assert(ref.isIndirect()); EndpointI[] endpoints = null; - Ice.ObjectPrx object = null; - cached.value = true; - String adapterId = ref.getAdapterId(); - Ice.Identity identity = ref.getIdentity(); - - try + cached.value = false; + if(!ref.isWellKnown()) { - if(adapterId.length() > 0) + endpoints = _table.getAdapterEndpoints(ref.getAdapterId(), ttl, cached); + if(!cached.value) { - endpoints = _table.getAdapterEndpoints(adapterId, ttl); - if(endpoints == null) + if(_background && endpoints != null) { - cached.value = false; - - if(ref.getInstance().traceLevels().location >= 1) - { - StringBuffer s = new StringBuffer(); - s.append("searching for adapter by id\n"); - s.append("adapter = " + adapterId); - ref.getInstance().initializationData().logger.trace( - ref.getInstance().traceLevels().locationCat, s.toString()); - } - - // - // Search the adapter in the location service if we didn't - // find it in the cache. - // - object = _locator.findAdapterById(adapterId); - if(object != null) - { - endpoints = ((Ice.ObjectPrxHelperBase)object).__reference().getEndpoints(); - - if(endpoints.length > 0) - { - _table.addAdapterEndpoints(adapterId, endpoints); - } - } + getAdapterRequest(ref).addCallback(ref, wellKnownRef, ttl, null); } - } - else - { - boolean objectCached = true; - object = _table.getProxy(identity, ttl); - if(object == null) + else { - objectCached = false; - - if(ref.getInstance().traceLevels().location >= 1) - { - StringBuffer s = new StringBuffer(); - s.append("searching for object by id\n"); - s.append("object = " + ref.getInstance().identityToString(identity)); - ref.getInstance().initializationData().logger.trace( - ref.getInstance().traceLevels().locationCat, s.toString()); - } - - object = _locator.findObjectById(identity); + return getAdapterRequest(ref).getEndpoints(ref, wellKnownRef, ttl, cached); } - - boolean endpointsCached = true; - if(object != null) + } + } + else + { + Reference r = _table.getObjectReference(ref.getIdentity(), ttl, cached); + if(!cached.value) + { + if(_background && r != null) { - Reference r = ((Ice.ObjectPrxHelperBase)object).__reference(); - if(!r.isIndirect()) - { - endpointsCached = false; - endpoints = r.getEndpoints(); - } - else if(!r.isWellKnown()) - { - Ice.BooleanHolder c = new Ice.BooleanHolder(); - endpoints = getEndpoints(r, ttl, c); - endpointsCached = c.value; - } + getObjectRequest(ref).addCallback(ref, null, ttl, null); } - - if(!objectCached && endpoints != null && endpoints.length > 0) + else { - _table.addProxy(identity, object); + return getObjectRequest(ref).getEndpoints(ref, null, ttl, cached); } - - cached.value = objectCached || endpointsCached; + } + + if(!r.isIndirect()) + { + endpoints = r.getEndpoints(); + } + else if(!r.isWellKnown()) + { + return getEndpoints(r, ref, ttl, cached); } } - catch(Exception ex) - { - getEndpointsException(ref, ex); - } - + + assert(endpoints != null); + cached.value = true; if(ref.getInstance().traceLevels().location >= 1) { - getEndpointsTrace(ref, endpoints, cached.value); + getEndpointsTrace(ref, endpoints, true); } + return endpoints; + } - return endpoints == null ? new EndpointI[0] : endpoints; + public void + getEndpoints(Reference ref, int ttl, GetEndpointsCallback callback) + { + getEndpoints(ref, null, ttl, callback); } public void - getEndpoints(final Reference ref, final int ttl, final GetEndpointsCallback callback) + getEndpoints(Reference ref, Reference wellKnownRef, int ttl, GetEndpointsCallback callback) { - final String adapterId = ref.getAdapterId(); - final Ice.Identity identity = ref.getIdentity(); - final Instance instance = ref.getInstance(); - if(adapterId.length() > 0) + assert(ref.isIndirect()); + EndpointI[] endpoints = null; + Ice.BooleanHolder cached = new Ice.BooleanHolder(); + if(!ref.isWellKnown()) { - EndpointI[] endpoints = _table.getAdapterEndpoints(adapterId, ttl); - if(endpoints == null) + endpoints = _table.getAdapterEndpoints(ref.getAdapterId(), ttl, cached); + if(!cached.value) { - if(instance.traceLevels().location >= 1) + if(_background && endpoints != null) { - StringBuffer s = new StringBuffer(); - s.append("searching for adapter by id\n"); - s.append("adapter = " + adapterId); - instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); + getAdapterRequest(ref).addCallback(ref, wellKnownRef, ttl, null); } - - // - // Search the adapter in the location service if we didn't - // find it in the cache. - // - _locator.findAdapterById_async(new Ice.AMI_Locator_findAdapterById() - { - public void - ice_response(Ice.ObjectPrx object) - { - EndpointI[] endpoints = null; - if(object != null) - { - endpoints = ((Ice.ObjectPrxHelperBase)object).__reference().getEndpoints(); - if(endpoints.length > 0) - { - _table.addAdapterEndpoints(adapterId, endpoints); - } - } - - if(instance.traceLevels().location >= 1) - { - getEndpointsTrace(ref, endpoints, false); - } - - if(endpoints == null) - { - callback.setEndpoints(new EndpointI[0], false); - } - else - { - callback.setEndpoints(endpoints, false); - } - } - - public void - ice_exception(Ice.UserException ex) - { - getEndpointsException(ref, ex, callback); - } - - public void - ice_exception(Ice.LocalException ex) - { - if(ex instanceof Ice.CollocationOptimizationException) - { - try - { - Ice.BooleanHolder cached = new Ice.BooleanHolder(); - callback.setEndpoints(getEndpoints(ref, ttl, cached), cached.value); - } - catch(Ice.LocalException e) - { - callback.setException(e); - } - } - else - { - getEndpointsException(ref, ex, callback); - } - } - }, adapterId); - return; - } - else - { - if(instance.traceLevels().location >= 1) + else { - getEndpointsTrace(ref, endpoints, true); + getAdapterRequest(ref).addCallback(ref, wellKnownRef, ttl, callback); + return; } - callback.setEndpoints(endpoints, true); - return; } } else { - Ice.ObjectPrx object = _table.getProxy(identity, ttl); - if(object == null) + Reference r = _table.getObjectReference(ref.getIdentity(), ttl, cached); + if(!cached.value) { - if(instance.traceLevels().location >= 1) + if(_background && r != null) { - StringBuffer s = new StringBuffer(); - s.append("searching for object by id\n"); - s.append("object = " + instance.identityToString(identity)); - instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); + getObjectRequest(ref).addCallback(ref, null, ttl, null); } - - _locator.findObjectById_async(new Ice.AMI_Locator_findObjectById() - { - public void - ice_response(Ice.ObjectPrx object) - { - getWellKnownObjectEndpoints(ref, object, ttl, false, callback); - } - - public void - ice_exception(Ice.UserException ex) - { - getEndpointsException(ref, ex, callback); - } + else + { + getObjectRequest(ref).addCallback(ref, null, ttl, callback); + return; + } + } - public void - ice_exception(Ice.LocalException ex) - { - if(ex instanceof Ice.CollocationOptimizationException) - { - try - { - Ice.BooleanHolder cached = new Ice.BooleanHolder(); - callback.setEndpoints(getEndpoints(ref, ttl, cached), cached.value); - } - catch(Ice.LocalException e) - { - callback.setException(e); - } - } - else - { - getEndpointsException(ref, ex, callback); - } - } - }, identity); - return; + if(!r.isIndirect()) + { + endpoints = r.getEndpoints(); } - else + else if(!r.isWellKnown()) { - getWellKnownObjectEndpoints(ref, object, ttl, true, callback); + getEndpoints(r, ref, ttl, callback); return; } } - } - public void - clearObjectCache(Reference ref) - { - assert(ref.isIndirect()); - if(ref.isWellKnown()) + assert(endpoints != null); + if(ref.getInstance().traceLevels().location >= 1) { - Ice.ObjectPrx object = _table.removeProxy(ref.getIdentity()); - if(object != null) - { - Reference r = ((Ice.ObjectPrxHelperBase)object).__reference(); - if(!r.isIndirect()) - { - if(ref.getInstance().traceLevels().location >= 2) - { - trace("removed endpoints from locator table", ref, r.getEndpoints()); - } - } - else if(!r.isWellKnown()) - { - clearCache(r); - } - } + getEndpointsTrace(ref, endpoints, true); + } + if(callback != null) + { + callback.setEndpoints(endpoints, true); } } - + public void clearCache(Reference ref) { @@ -365,10 +522,9 @@ public final class LocatorInfo } else { - Ice.ObjectPrx object = _table.removeProxy(ref.getIdentity()); - if(object != null) + Reference r = _table.removeObjectReference(ref.getIdentity()); + if(r != null) { - Reference r = ((Ice.ObjectPrxHelperBase)object).__reference(); if(!r.isIndirect()) { if(ref.getInstance().traceLevels().location >= 2) @@ -486,121 +642,141 @@ public final class LocatorInfo } private void - getEndpointsException(Reference ref, Exception exc, GetEndpointsCallback callback) + getEndpointsTrace(Reference ref, EndpointI[] endpoints, boolean cached) { - try - { - getEndpointsException(ref, exc); - } - catch(Ice.LocalException ex) - { - callback.setException(ex); - } - catch(Exception ex) + if(endpoints != null && endpoints.length > 0) { - assert(false); + if(cached) + { + trace("found endpoints in locator table", ref, endpoints); + } + else + { + trace("retrieved endpoints from locator, adding to locator table", ref, endpoints); + } } - } - - private void - getWellKnownObjectEndpoints(final Reference ref, - final Ice.ObjectPrx object, - final int ttl, - final boolean objectCached, - final GetEndpointsCallback callback) - { - EndpointI[] endpoints = null; - if(object != null) + else { - Reference r = ((Ice.ObjectPrxHelperBase)object).__reference(); - if(!r.isIndirect()) + final Instance instance = ref.getInstance(); + StringBuffer s = new StringBuffer(); + s.append("no endpoints configured for "); + if(ref.getAdapterId().length() > 0) { - endpoints = r.getEndpoints(); + s.append("adapter\n"); + s.append("adapter = " + ref.getAdapterId() + "\n"); } - else if(!r.isWellKnown()) + else { - getEndpoints(r, ttl, new GetEndpointsCallback() - { - public void - setEndpoints(EndpointI[] endpoints, boolean endpointsCached) - { - if(!objectCached && endpoints != null && endpoints.length > 0) - { - _table.addProxy(ref.getIdentity(), object); - } - - if(ref.getInstance().traceLevels().location >= 1) - { - getEndpointsTrace(ref, endpoints, objectCached || endpointsCached); - } - - callback.setEndpoints(endpoints, objectCached || endpointsCached); - } - - public void - setException(Ice.LocalException ex) - { - callback.setException(ex); - } - }); - return; + s.append("object\n"); + s.append("object = " + instance.identityToString(ref.getIdentity()) + "\n"); } + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); } - - if(!objectCached && endpoints != null && endpoints.length > 0) + } + + synchronized private Request + getAdapterRequest(Reference ref) + { + if(ref.getInstance().traceLevels().location >= 1) { - _table.addProxy(ref.getIdentity(), object); + Instance instance = ref.getInstance(); + StringBuffer s = new StringBuffer(); + s.append("searching for adapter by id\nadapter="); + s.append(ref.getAdapterId()); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); } - if(ref.getInstance().traceLevels().location >= 1) + Request request = _adapterRequests.get(ref.getAdapterId()); + if(request != null) { - getEndpointsTrace(ref, endpoints, objectCached); + return request; } + request = new AdapterRequest(this, ref); + _adapterRequests.put(ref.getAdapterId(), request); + return request; + } - if(endpoints == null) + synchronized private Request + getObjectRequest(Reference ref) + { + if(ref.getInstance().traceLevels().location >= 1) { - callback.setEndpoints(new EndpointI[0], false); + Instance instance = ref.getInstance(); + StringBuffer s = new StringBuffer(); + s.append("searching for object by id\nobject = "); + s.append(instance.identityToString(ref.getIdentity())); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); } - else + + Request request = _objectRequests.get(ref.getIdentity()); + if(request != null) { - callback.setEndpoints(endpoints, objectCached); + return request; } + request = new ObjectRequest(this, ref); + _objectRequests.put(ref.getIdentity(), request); + return request; } - + private void - getEndpointsTrace(Reference ref, EndpointI[] endpoints, boolean cached) + finishRequest(Reference ref, java.util.List<Reference> wellKnownRefs, Ice.ObjectPrx proxy, boolean notRegistered) { - if(endpoints != null && endpoints.length > 0) + if(proxy == null || ((Ice.ObjectPrxHelperBase)proxy).__reference().isIndirect()) { - if(cached) + // + // Remove the cached references of well-known objects for which we tried + // to resolved the endpoints if these endpoints are empty. + // + for(Reference r : wellKnownRefs) { - trace("found endpoints in locator table", ref, endpoints); + _table.removeObjectReference(r.getIdentity()); } - else + } + + if(!ref.isWellKnown()) + { + if(proxy != null && !((Ice.ObjectPrxHelperBase)proxy).__reference().isIndirect()) { - trace("retrieved endpoints from locator, adding to locator table", ref, endpoints); + // Cache the adapter endpoints. + _table.addAdapterEndpoints(ref.getAdapterId(), + ((Ice.ObjectPrxHelperBase)proxy).__reference().getEndpoints()); + } + else if(notRegistered) // If the adapter isn't registered anymore, remove it from the cache. + { + _table.removeAdapterEndpoints(ref.getAdapterId()); + } + + synchronized(this) + { + assert(_adapterRequests.get(ref.getAdapterId()) != null); + _adapterRequests.remove(ref.getAdapterId()); } } else { - final Instance instance = ref.getInstance(); - StringBuffer s = new StringBuffer(); - s.append("no endpoints configured for "); - if(ref.getAdapterId().length() > 0) + if(proxy != null && !((Ice.ObjectPrxHelperBase)proxy).__reference().isWellKnown()) { - s.append("adapter\n"); - s.append("adapter = " + ref.getAdapterId() + "\n"); + // Cache the well-known object reference. + _table.addObjectReference(ref.getIdentity(), ((Ice.ObjectPrxHelperBase)proxy).__reference()); } - else + else if(notRegistered) // If the well-known object isn't registered anymore, remove it from the cache. { - s.append("object\n"); - s.append("object = " + instance.identityToString(ref.getIdentity()) + "\n"); + _table.removeObjectReference(ref.getIdentity()); + } + + synchronized(this) + { + assert(_objectRequests.get(ref.getIdentity()) != null); + _objectRequests.remove(ref.getIdentity()); } - instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); } } - + private final Ice.LocatorPrx _locator; private Ice.LocatorRegistryPrx _locatorRegistry; private final LocatorTable _table; + private final boolean _background; + + private java.util.Map<String, Request> _adapterRequests = new java.util.HashMap<String, Request>(); + private java.util.Map<Ice.Identity, Request> _objectRequests = new java.util.HashMap<Ice.Identity, Request>(); } |