diff options
Diffstat (limited to 'js/src/Ice/RouterInfo.js')
-rw-r--r-- | js/src/Ice/RouterInfo.js | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/js/src/Ice/RouterInfo.js b/js/src/Ice/RouterInfo.js new file mode 100644 index 00000000000..1a15ee3c414 --- /dev/null +++ b/js/src/Ice/RouterInfo.js @@ -0,0 +1,229 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +(function(global){ + require("Ice/Class"); + require("Ice/ArrayUtil"); + require("Ice/Debug"); + require("Ice/HashMap"); + require("Ice/Promise"); + require("Ice/LocalException"); + require("Ice/Exception"); + + var Ice = global.Ice || {}; + + var ArrayUtil = Ice.ArrayUtil; + var Debug = Ice.Debug; + var HashMap = Ice.HashMap; + var Promise = Ice.Promise; + + var RouterInfo = Ice.Class({ + __init__: function(router) + { + this._router = router; + + Debug.assert(this._router !== null); + + this._clientEndpoints = null; + this._serverEndpoints = null; + this._adapter = null; + this._identities = new HashMap(); // Set<Identity> = Map<Identity, 1> + this._identities.keyComparator = HashMap.compareEquals; + this._evictedIdentities = []; + }, + destroy: function() + { + this._clientEndpoints = []; + this._serverEndpoints = []; + this._adapter = null; + this._identities.clear(); + }, + equals: function(rhs) + { + if(this === rhs) + { + return true; + } + + if(rhs instanceof RouterInfo) + { + return this._router.equals(rhs._router); + } + + return false; + }, + hashCode: function() + { + return this._router.hashCode(); + }, + getRouter: function() + { + // + // No mutex lock necessary, _router is immutable. + // + return this._router; + }, + getClientEndpoints: function() + { + var promise = new Promise(); + + if(this._clientEndpoints !== null) + { + promise.succeed(this._clientEndpoints); + } + else + { + var self = this; + this._router.getClientProxy().then( + function(clientProxy) + { + self.setClientEndpoints(clientProxy, promise); + }).exception( + function(ex) + { + promise.fail(ex); + }); + } + + return promise; + }, + getServerEndpoints: function() + { + if(this._serverEndpoints !== null) // Lazy initialization. + { + return new Promise().succeed(this._serverEndpoints); + } + else + { + var self = this; + return this._router.getServerProxy().then( + function(proxy) + { + return self.setServerEndpoints(proxy); + }); + } + }, + addProxy: function(proxy) + { + Debug.assert(proxy !== null); + + if(this._identities.has(proxy.ice_getIdentity())) + { + // + // Only add the proxy to the router if it's not already in our local map. + // + return new Promise().succeed(); + } + else + { + var self = this; + return this._router.addProxies([ proxy ]).then( + function(evictedProxies) + { + self.addAndEvictProxies(proxy, evictedProxies); + }); + } + }, + setAdapter: function(adapter) + { + this._adapter = adapter; + }, + getAdapter: function() + { + return this._adapter; + }, + clearCache: function(ref) + { + this._identities.delete(ref.getIdentity()); + }, + setClientEndpoints: function(clientProxy, promise) + { + if(this._clientEndpoints === null) + { + if(clientProxy === null) + { + // + // If getClientProxy() return nil, use router endpoints. + // + this._clientEndpoints = this._router.__reference().getEndpoints(); + promise.succeed(this._clientEndpoints); + } + 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. + // + var self = this; + this._router.ice_getConnection().then( + function(con) + { + var proxy = clientProxy.ice_timeout(con.timeout()); + self._clientEndpoints = proxy.__reference().getEndpoints(); + promise.succeed(self._clientEndpoints); + }).exception( + function(ex) + { + promise.fail(ex); + }); + } + } + else + { + promise.succeed(this._clientEndpoints); + } + }, + setServerEndpoints: function(serverProxy) + { + if(serverProxy === null) + { + throw new Ice.NoEndpointException(); + } + + serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed. + this._serverEndpoints = serverProxy.__reference().getEndpoints(); + return this._serverEndpoints; + }, + addAndEvictProxies: function(proxy, 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. + // + var index = ArrayUtil.indexOf(this._evictedIdentities, proxy.ice_getIdentity(), + function(i1, i2) { return i1.equals(i2); }); + if(index >= 0) + { + this._evictedIdentities.splice(index, 1); + } + else + { + // + // If we successfully added the proxy to the router, + // we add it to our local map. + // + this._identities.set(proxy.ice_getIdentity(), 1); + } + + // + // We also must remove whatever proxies the router evicted. + // + for(var i = 0; i < evictedProxies.length; ++i) + { + this._identities.delete(evictedProxies[i].ice_getIdentity()); + } + } + }); + Ice.RouterInfo = RouterInfo; + global.Ice = Ice; +}(typeof (global) === "undefined" ? window : global)); |