IceInternal.RouterInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ice-compat Show documentation
Show all versions of ice-compat Show documentation
Ice is a comprehensive RPC framework that helps you build distributed applications with minimal effort using familiar object-oriented idioms
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
package IceInternal;
public final class RouterInfo
{
interface GetClientEndpointsCallback
{
void setEndpoints(EndpointI[] endpoints);
void setException(Ice.LocalException ex);
}
interface AddProxyCallback
{
void addedProxy();
void setException(Ice.LocalException ex);
}
RouterInfo(Ice.RouterPrx router)
{
_router = router;
assert(_router != null);
}
synchronized public void
destroy()
{
_clientEndpoints = new EndpointI[0];
_adapter = null;
_identities.clear();
}
@Override
public boolean
equals(java.lang.Object obj)
{
if(this == obj)
{
return true;
}
if(obj instanceof RouterInfo)
{
return _router.equals(((RouterInfo)obj)._router);
}
return false;
}
@Override
public int
hashCode()
{
return _router.hashCode();
}
public Ice.RouterPrx
getRouter()
{
//
// No mutex lock necessary, _router is immutable.
//
return _router;
}
public EndpointI[]
getClientEndpoints()
{
synchronized(this)
{
if(_clientEndpoints != null) // Lazy initialization.
{
return _clientEndpoints;
}
}
Ice.BooleanOptional hasRoutingTable = new Ice.BooleanOptional();
Ice.ObjectPrx proxy = _router.getClientProxy(hasRoutingTable);
return setClientEndpoints(proxy, hasRoutingTable.isSet() ? hasRoutingTable.get() : true);
}
public void
getClientEndpoints(final GetClientEndpointsCallback callback)
{
EndpointI[] clientEndpoints = null;
synchronized(this)
{
clientEndpoints = _clientEndpoints;
}
if(clientEndpoints != null)
{
callback.setEndpoints(clientEndpoints);
return;
}
_router.begin_getClientProxy(new Ice.Callback_Router_getClientProxy()
{
@Override
public void
response(Ice.ObjectPrx clientProxy, Ice.BooleanOptional hasRoutingTable)
{
callback.setEndpoints(setClientEndpoints(clientProxy,
hasRoutingTable.isSet() ? hasRoutingTable.get() : true));
}
@Override
public void
exception(Ice.LocalException ex)
{
callback.setException(ex);
}
});
}
public EndpointI[]
getServerEndpoints()
{
Ice.ObjectPrx serverProxy = _router.getServerProxy();
if(serverProxy == null)
{
throw new Ice.NoEndpointException();
}
serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
return ((Ice.ObjectPrxHelperBase)serverProxy)._getReference().getEndpoints();
}
public boolean
addProxy(final Ice.ObjectPrx proxy, final AddProxyCallback callback)
{
assert(proxy != null);
synchronized(this)
{
if(!_hasRoutingTable)
{
return true; // The router implementation doesn't maintain a routing table.
}
if(_identities.contains(proxy.ice_getIdentity()))
{
//
// Only add the proxy to the router if it's not already in our local map.
//
return true;
}
}
_router.begin_addProxies(new Ice.ObjectPrx[] { proxy },
new Ice.Callback_Router_addProxies()
{
@Override
public void
response(Ice.ObjectPrx[] evictedProxies)
{
addAndEvictProxies(proxy, evictedProxies);
callback.addedProxy();
}
@Override
public void
exception(Ice.LocalException ex)
{
callback.setException(ex);
}
});
return false;
}
public synchronized void
setAdapter(Ice.ObjectAdapter adapter)
{
_adapter = adapter;
}
public synchronized Ice.ObjectAdapter
getAdapter()
{
return _adapter;
}
public synchronized void clearCache(Reference ref)
{
_identities.remove(ref.getIdentity());
}
private synchronized EndpointI[]
setClientEndpoints(Ice.ObjectPrx clientProxy, boolean hasRoutingTable)
{
if(_clientEndpoints == null)
{
_hasRoutingTable = hasRoutingTable;
if(clientProxy == null)
{
//
// If getClientProxy() return nil, use router endpoints.
//
_clientEndpoints = ((Ice.ObjectPrxHelperBase)_router)._getReference().getEndpoints();
}
else
{
clientProxy = clientProxy.ice_router(null); // The client proxy cannot be routed.
//
// In order to avoid creating a new connection to the
// router, we must use the same timeout as the already
// existing connection.
//
if(_router.ice_getConnection() != null)
{
clientProxy = clientProxy.ice_timeout(_router.ice_getConnection().timeout());
}
_clientEndpoints = ((Ice.ObjectPrxHelperBase)clientProxy)._getReference().getEndpoints();
}
}
return _clientEndpoints;
}
private synchronized void
addAndEvictProxies(Ice.ObjectPrx proxy, Ice.ObjectPrx[] evictedProxies)
{
//
// Check if the proxy hasn't already been evicted by a
// concurrent addProxies call. If it's the case, don't
// add it to our local map.
//
int index = _evictedIdentities.indexOf(proxy.ice_getIdentity());
if(index >= 0)
{
_evictedIdentities.remove(index);
}
else
{
//
// If we successfully added the proxy to the router,
// we add it to our local map.
//
_identities.add(proxy.ice_getIdentity());
}
//
// We also must remove whatever proxies the router evicted.
//
for(Ice.ObjectPrx p : evictedProxies)
{
if(!_identities.remove(p.ice_getIdentity()))
{
//
// It's possible for the proxy to not have been
// added yet in the local map if two threads
// concurrently call addProxies.
//
_evictedIdentities.add(p.ice_getIdentity());
}
}
}
private final Ice.RouterPrx _router;
private EndpointI[] _clientEndpoints;
private Ice.ObjectAdapter _adapter;
private java.util.Set _identities = new java.util.HashSet();
private java.util.List _evictedIdentities = new java.util.ArrayList();
private boolean _hasRoutingTable;
}