summaryrefslogtreecommitdiff
path: root/js/src/Ice/ProxyFactory.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/Ice/ProxyFactory.js')
-rw-r--r--js/src/Ice/ProxyFactory.js291
1 files changed, 291 insertions, 0 deletions
diff --git a/js/src/Ice/ProxyFactory.js b/js/src/Ice/ProxyFactory.js
new file mode 100644
index 00000000000..5c62625a772
--- /dev/null
+++ b/js/src/Ice/ProxyFactory.js
@@ -0,0 +1,291 @@
+// **********************************************************************
+//
+// 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/Debug");
+ require("Ice/ExUtil");
+ require("Ice/HashMap");
+ require("Ice/ObjectPrx");
+ require("Ice/StringUtil");
+ require("Ice/Identity");
+ require("Ice/Reference");
+ require("Ice/LocalException");
+
+ var Ice = global.Ice || {};
+
+ var Debug = Ice.Debug;
+ var ExUtil = Ice.ExUtil;
+ var HashMap = Ice.HashMap;
+ var ObjectPrx = Ice.ObjectPrx;
+ var StringUtil = Ice.StringUtil;
+ var Identity = Ice.Identity;
+
+ //
+ // Only for use by Instance.
+ //
+ var ProxyFactory = Ice.Class({
+ __init__: function(instance)
+ {
+ this._instance = instance;
+
+ var arr = this._instance.initializationData().properties.getPropertyAsList("Ice.RetryIntervals");
+
+ if(arr.length > 0)
+ {
+ this._retryIntervals = [];
+
+ for(var i = 0; i < arr.length; i++)
+ {
+ var v;
+
+ try
+ {
+ v = StringUtil.toInt(arr[i]);
+ }
+ catch(ex)
+ {
+ v = 0;
+ }
+
+ //
+ // If -1 is the first value, no retry and wait intervals.
+ //
+ if(i === 0 && v === -1)
+ {
+ this._retryIntervals = [ 0 ];
+ break;
+ }
+
+ this._retryIntervals[i] = v > 0 ? v : 0;
+ }
+ }
+ else
+ {
+ this._retryIntervals = [ 0 ];
+ }
+ },
+ stringToProxy: function(str)
+ {
+ var ref = this._instance.referenceFactory().createFromString(str, null);
+ return this.referenceToProxy(ref);
+ },
+ proxyToString: function(proxy)
+ {
+ if(proxy !== null)
+ {
+ return proxy.__reference().toString();
+ }
+ else
+ {
+ return "";
+ }
+ },
+ propertyToProxy: function(prefix)
+ {
+ var proxy = this._instance.initializationData().properties.getProperty(prefix);
+ var ref = this._instance.referenceFactory().createFromString(proxy, prefix);
+ return this.referenceToProxy(ref);
+ },
+ proxyToProperty: function(proxy, prefix)
+ {
+ if(proxy !== null)
+ {
+ return proxy.__reference().toProperty(prefix);
+ }
+ else
+ {
+ return new HashMap();
+ }
+ },
+ streamToProxy: function(s, type)
+ {
+ var ident = new Identity();
+ ident.__read(s);
+
+ var ref = this._instance.referenceFactory().createFromStream(ident, s);
+ return this.referenceToProxy(ref, type);
+ },
+ referenceToProxy: function(ref, type)
+ {
+ if(ref !== null)
+ {
+ var proxy = type ? new type() : new ObjectPrx();
+ proxy.__setup(ref);
+ return proxy;
+ }
+ else
+ {
+ return null;
+ }
+ },
+ proxyToStream: function(proxy, s)
+ {
+ if(proxy !== null)
+ {
+ var ref = proxy.__reference();
+ ref.getIdentity().__write(s);
+ ref.streamWrite(s);
+ }
+ else
+ {
+ var ident = new Identity("", "");
+ ident.__write(s);
+ }
+ },
+ checkRetryAfterException: function(ex, ref, sleepInterval, cnt)
+ {
+ var traceLevels = this._instance.traceLevels();
+ var logger = this._instance.initializationData().logger;
+
+ //
+ // We don't retry batch requests because the exception might have caused
+ // the all the requests batched with the connection to be aborted and we
+ // want the application to be notified.
+ //
+ if(ref.getMode() === Ice.Reference.ModeBatchOneway || ref.getMode() === Ice.Reference.ModeBatchDatagram)
+ {
+ throw ex;
+ }
+
+ if(ex instanceof Ice.ObjectNotExistException)
+ {
+ var one = ex;
+
+ if(ref.getRouterInfo() !== null && one.operation === "ice_add_proxy")
+ {
+ //
+ // If we have a router, an ObjectNotExistException with an
+ // operation name "ice_add_proxy" indicates to the client
+ // that the router isn't aware of the proxy (for example,
+ // because it was evicted by the router). In this case, we
+ // must *always* retry, so that the missing proxy is added
+ // to the router.
+ //
+
+ ref.getRouterInfo().clearCache(ref);
+
+ if(traceLevels.retry >= 1)
+ {
+ logger.trace(traceLevels.retryCat, "retrying operation call to add proxy to router\n" +
+ ExUtil.toString(ex));
+ }
+
+ if(sleepInterval !== null)
+ {
+ sleepInterval.value = 0;
+ }
+ return cnt; // We must always retry, so we don't look at the retry count.
+ }
+ else if(ref.isIndirect())
+ {
+ //
+ // We retry ObjectNotExistException if the reference is
+ // indirect.
+ //
+
+ if(ref.isWellKnown())
+ {
+ var li = ref.getLocatorInfo();
+ if(li !== null)
+ {
+ li.clearCache(ref);
+ }
+ }
+ }
+ else
+ {
+ //
+ // For all other cases, we don't retry ObjectNotExistException.
+ //
+ throw ex;
+ }
+ }
+ else if(ex instanceof Ice.RequestFailedException)
+ {
+ //
+ // For all other cases, we don't retry ObjectNotExistException
+ //
+ throw ex;
+ }
+
+ //
+ // 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.
+ //
+ // 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.
+ //
+ // 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(ex instanceof Ice.MarshalException)
+ {
+ throw ex;
+ }
+
+ ++cnt;
+ Debug.assert(cnt > 0);
+
+ var interval;
+ if(cnt === (this._retryIntervals.length + 1) && ex instanceof Ice.CloseConnectionException)
+ {
+ //
+ // A close connection exception is always retried at least once, even if the retry
+ // limit is reached.
+ //
+ interval = 0;
+ }
+ else if(cnt > this._retryIntervals.length)
+ {
+ if(traceLevels.retry >= 1)
+ {
+ logger.trace(traceLevels.retryCat, "cannot retry operation call because retry limit has been exceeded\n" +
+ ExUtil.toString(ex));
+ }
+ throw ex;
+ }
+ else
+ {
+ interval = this._retryIntervals[cnt - 1];
+ }
+
+ if(traceLevels.retry >= 1)
+ {
+ var msg = "retrying operation call";
+ if(interval > 0)
+ {
+ msg += " in " + interval + "ms";
+ }
+ msg += " because of exception\n" + ExUtil.toString(ex);
+ logger.trace(traceLevels.retryCat, msg);
+ }
+
+ Debug.assert(sleepInterval !== null);
+ sleepInterval.value = interval;
+
+ return cnt;
+ }
+ });
+
+ Ice.ProxyFactory = ProxyFactory;
+ global.Ice = Ice;
+}(typeof (global) === "undefined" ? window : global));