summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rwxr-xr-xjs/allTests.py1
-rw-r--r--js/demo/Ice/hello/Client.js2
-rw-r--r--js/src/Ice/ConnectRequestHandler.js134
-rw-r--r--js/src/Ice/ConnectionRequestHandler.js8
-rw-r--r--js/src/Ice/Instance.js25
-rw-r--r--js/src/Ice/Makefile1
-rw-r--r--js/src/Ice/Makefile.mak1
-rw-r--r--js/src/Ice/ObjectPrx.js10
-rw-r--r--js/src/Ice/Operation.js1
-rw-r--r--js/src/Ice/Promise.js11
-rw-r--r--js/src/Ice/RequestHandlerFactory.js60
-rw-r--r--js/test/Common/TestSuite.js2
-rw-r--r--js/test/Common/index.html1
-rw-r--r--js/test/Ice/Makefile1
-rw-r--r--js/test/Ice/Makefile.mak1
-rw-r--r--js/test/Ice/hold/.depend.mak3
-rw-r--r--js/test/Ice/hold/.gitignore2
-rw-r--r--js/test/Ice/hold/Client.js307
-rw-r--r--js/test/Ice/hold/Makefile23
-rw-r--r--js/test/Ice/hold/Makefile.mak20
-rw-r--r--js/test/Ice/hold/Test.ice24
-rw-r--r--js/test/Ice/hold/run.js10
-rwxr-xr-xjs/test/Ice/hold/run.py24
23 files changed, 577 insertions, 95 deletions
diff --git a/js/allTests.py b/js/allTests.py
index 7811095379a..ca2f88504e8 100755
--- a/js/allTests.py
+++ b/js/allTests.py
@@ -34,6 +34,7 @@ tests = [
("Ice/exceptionsBidir", ["once"]),
("Ice/facets", ["core"]),
("Ice/facetsBidir", ["core"]),
+ ("Ice/hold", ["core"]),
("Ice/inheritance", ["once"]),
("Ice/inheritanceBidir", ["once"]),
("Ice/location", ["once"]),
diff --git a/js/demo/Ice/hello/Client.js b/js/demo/Ice/hello/Client.js
index f06187a82bd..6806e7250f4 100644
--- a/js/demo/Ice/hello/Client.js
+++ b/js/demo/Ice/hello/Client.js
@@ -187,6 +187,6 @@ Ice.Promise.try(
},
function(ex)
{
- console.log(ex.toString());
+ console.log(ex);
process.exit(1);
});
diff --git a/js/src/Ice/ConnectRequestHandler.js b/js/src/Ice/ConnectRequestHandler.js
index 22bfb213581..5ad7ae6cdc6 100644
--- a/js/src/Ice/ConnectRequestHandler.js
+++ b/js/src/Ice/ConnectRequestHandler.js
@@ -44,42 +44,40 @@ var ConnectRequestHandler = Ice.Class({
this._reference = ref;
this._response = ref.getMode() === ReferenceMode.ModeTwoway;
this._proxy = proxy;
+ this._proxies = [];
this._batchAutoFlush = ref.getInstance().initializationData().properties.getPropertyAsIntWithDefault(
"Ice.BatchAutoFlush", 1) > 0 ? true : false;
this._initialized = false;
- this._flushing = false;
this._batchRequestInProgress = false;
this._batchRequestsSize = Protocol.requestBatchHdr.length;
this._batchStream =
new BasicStream(ref.getInstance(), Protocol.currentProtocolEncoding, this._batchAutoFlush);
- this._updateRequestHandler = false;
this._connection = null;
this._compress = false;
this._exception = null;
this._requests = [];
- this._updateRequestHandler = false;
},
- connect: function()
+ connect: function(proxy)
{
var self = this;
- var proxy = this._proxy;
- try
+ if(proxy === this._proxy)
{
- this._reference.getConnection().then(
- function(connection, compress)
- {
- self.setConnection(connection, compress);
- }).exception(
- function(ex)
- {
- self.setException(ex);
- });
+ this._reference.getConnection().then(function(connection, compress)
+ {
+ self.setConnection(connection, compress);
+ },
+ function(ex)
+ {
+ self.setException(ex);
+ });
+ }
+ try
+ {
if(!this.initialized())
{
- // The proxy request handler will be updated when the connection is set.
- this._updateRequestHandler = true;
+ this._proxies.push(proxy);
return this;
}
}
@@ -89,11 +87,15 @@ var ConnectRequestHandler = Ice.Class({
throw ex;
}
- Debug.Assert(this._connection !== null);
-
- var handler = new ConnectionRequestHandler(this._reference, this._connection, this._compress);
- proxy.setRequestHandler__(this, handler);
- return handler;
+ if(this._connectionRequestHandler)
+ {
+ proxy.__setRequestHandler(this, this._connectionRequestHandler);
+ return this._connectionRequestHandler;
+ }
+ else
+ {
+ return this;
+ }
},
update: function(previousHandler, newHandler)
{
@@ -148,7 +150,6 @@ var ConnectRequestHandler = Ice.Class({
this._batchAutoFlush);
this._batchStream.swap(dummy);
this._batchRequestsSize = Protocol.requestBatchHdr.length;
-
return;
}
this._connection.abortBatchRequest();
@@ -218,7 +219,6 @@ var ConnectRequestHandler = Ice.Class({
setConnection: function(connection, compress)
{
Debug.assert(this._exception === null && this._connection === null);
- Debug.assert(this._updateRequestHandler || this._requests.length === 0);
this._connection = connection;
this._compress = compress;
@@ -231,24 +231,19 @@ var ConnectRequestHandler = Ice.Class({
if(ri !== null)
{
var self = this;
- var promise = ri.addProxy(this._proxy).then(
- function()
- {
- //
- // The proxy was added to the router info, we're now ready to send the
- // queued requests.
- //
- self.flushRequests();
- }).exception(
- function(ex)
- {
- self.setException(ex);
- });
-
- if(!promise.completed())
- {
- return; // The request handler will be initialized once addProxy completes.
- }
+ ri.addProxy(this._proxy).then(function()
+ {
+ //
+ // The proxy was added to the router info, we're now ready to send the
+ // queued requests.
+ //
+ self.flushRequests();
+ },
+ function(ex)
+ {
+ self.setException(ex);
+ });
+ return; // The request handler will be initialized once addProxy completes.
}
//
@@ -259,19 +254,21 @@ var ConnectRequestHandler = Ice.Class({
setException: function(ex)
{
Debug.assert(!this._initialized && this._exception === null);
- Debug.assert(this._updateRequestHandler || this._requests.length === 0);
this._exception = ex;
+ this._proxies.length = 0;
this._proxy = null; // Break cyclic reference count.
- //
- // If some requests were queued, we notify them of the failure.
- //
- if(this._requests.length > 0)
+ this.flushRequestsWithException(ex);
+
+ try
{
- this.flushRequestsWithException(ex);
+ this._reference.getInstance().requestHandlerFactory().removeRequestHandler(this._reference, this);
+ }
+ catch(exc)
+ {
+ // Ignore
}
-
},
initialized: function()
{
@@ -296,13 +293,6 @@ var ConnectRequestHandler = Ice.Class({
{
Debug.assert(this._connection !== null && !this._initialized);
- //
- // We set the _flushing flag to true to prevent any additional queuing. Callers
- // might block for a little while as the queued requests are being sent but this
- // shouldn't be an issue as the request sends are non-blocking.
- //
- this._flushing = true;
-
try
{
while(this._requests.length > 0)
@@ -358,27 +348,31 @@ var ConnectRequestHandler = Ice.Class({
}
}
- //
- // We've finished sending the queued requests and the request handler now send
- // the requests over the connection directly. It's time to substitute the
- // request handler of the proxy with the more efficient connection request
- // handler which does not have any synchronization. This also breaks the cyclic
- // reference count with the proxy.
- //
- // NOTE: _updateRequestHandler is immutable once _flushing = true
- //
- if(this._updateRequestHandler && this._exception === null)
+ if(this._reference.getCacheConnection() && this._exception === null)
{
- this._proxy.__setRequestHandler(this, new ConnectionRequestHandler(this._reference, this._connection,
- this._compress));
+ this._connectionRequestHandler = new ConnectionRequestHandler(this._reference,
+ this._connection,
+ this._compress);
+ for(var i in this._proxies)
+ {
+ this._proxies[i].__setRequestHandler(this, this._connectionRequestHandler);
+ }
}
Debug.assert(!this._initialized);
if(this._exception === null)
{
this._initialized = true;
- this._flushing = false;
}
+ try
+ {
+ this._reference.getInstance().requestHandlerFactory().removeRequestHandler(this._reference, this);
+ }
+ catch(exc)
+ {
+ // Ignore
+ }
+ this._proxies.length = 0;
this._proxy = null; // Break cyclic reference count.
},
flushRequestsWithException: function()
@@ -391,7 +385,7 @@ var ConnectRequestHandler = Ice.Class({
request.out.__completedEx(this._exception);
}
}
- this._requests = [];
+ this._requests.length = 0;
}
});
diff --git a/js/src/Ice/ConnectionRequestHandler.js b/js/src/Ice/ConnectionRequestHandler.js
index 914e620c040..eabfd274ec8 100644
--- a/js/src/Ice/ConnectionRequestHandler.js
+++ b/js/src/Ice/ConnectionRequestHandler.js
@@ -21,10 +21,10 @@ var ConnectionRequestHandler = Ice.Class({
this._connection = connection;
this._compress = compress;
},
- // connect : function()
- // {
- // This request handler is only created after connection binding.
- // }
+ connect : function()
+ {
+ return this;
+ },
update: function(previousHandler, newHandler)
{
try
diff --git a/js/src/Ice/Instance.js b/js/src/Ice/Instance.js
index 0ac7976d627..ab9fdbfb710 100644
--- a/js/src/Ice/Instance.js
+++ b/js/src/Ice/Instance.js
@@ -34,6 +34,7 @@ Ice.__M.require(module,
"../Ice/TcpEndpointFactory",
"../Ice/WSEndpointFactory",
"../Ice/Reference",
+ "../Ice/RequestHandlerFactory",
"../Ice/LocalException",
"../Ice/Exception",
"../Ice/ProcessLogger",
@@ -61,6 +62,7 @@ var RouterManager = Ice.RouterManager;
var Timer = Ice.Timer;
var TraceLevels = Ice.TraceLevels;
var ReferenceFactory = Ice.ReferenceFactory;
+var RequestHandlerFactory = Ice.RequestHandlerFactory;
var ACMConfig = Ice.ACMConfig;
var StateActive = 0;
@@ -84,6 +86,7 @@ var Instance = Ice.Class({
this._routerManager = null;
this._locatorManager = null;
this._referenceFactory = null;
+ this._requestHandlerFactory = null;
this._proxyFactory = null;
this._outgoingConnectionFactory = null;
this._servantFactoryManager = null;
@@ -145,6 +148,16 @@ var Instance = Ice.Class({
Debug.assert(this._referenceFactory !== null);
return this._referenceFactory;
},
+ requestHandlerFactory: function()
+ {
+ if(this._state === StateDestroyed)
+ {
+ throw new Ice.CommunicatorDestroyedException();
+ }
+
+ Debug.assert(this._requestHandlerFactory !== null);
+ return this._requestHandlerFactory;
+ },
proxyFactory: function()
{
if(this._state === StateDestroyed)
@@ -332,6 +345,8 @@ var Instance = Ice.Class({
this._referenceFactory = new ReferenceFactory(this, communicator);
+ this._requestHandlerFactory = new RequestHandlerFactory(this, communicator);
+
this._proxyFactory = new ProxyFactory(this);
this._endpointFactoryManager = new EndpointFactoryManager(this);
@@ -482,11 +497,11 @@ var Instance = Ice.Class({
self._servantFactoryManager = null;
}
- if(self._referenceFactory)
- {
- //self._referenceFactory.destroy(); // No destroy function defined.
- self._referenceFactory = null;
- }
+ //self._referenceFactory.destroy(); // No destroy function defined.
+ self._referenceFactory = null;
+
+ //self._requestHandlerFactory.destroy(); // No destroy function defined.
+ self._requestHandlerFactory = null;
// self._proxyFactory.destroy(); // No destroy function defined.
self._proxyFactory = null;
diff --git a/js/src/Ice/Makefile b/js/src/Ice/Makefile
index b9cdf2525f9..cd453b0347e 100644
--- a/js/src/Ice/Makefile
+++ b/js/src/Ice/Makefile
@@ -96,6 +96,7 @@ COMMON_SRCS = \
ProxyFactory.js \
Reference.js \
ReferenceMode.js \
+ RequestHandlerFactory.js \
RetryException.js \
RetryQueue.js \
RouterInfo.js \
diff --git a/js/src/Ice/Makefile.mak b/js/src/Ice/Makefile.mak
index 5c1138f3870..c12fa2d9e72 100644
--- a/js/src/Ice/Makefile.mak
+++ b/js/src/Ice/Makefile.mak
@@ -92,6 +92,7 @@ COMMON_SRCS = \
ProxyFactory.js \
Reference.js \
ReferenceMode.js \
+ RequestHandlerFactory.js \
RetryException.js \
RetryQueue.js \
RouterInfo.js \
diff --git a/js/src/Ice/ObjectPrx.js b/js/src/Ice/ObjectPrx.js
index 455f10bcbca..ef653e7d5a1 100644
--- a/js/src/Ice/ObjectPrx.js
+++ b/js/src/Ice/ObjectPrx.js
@@ -13,7 +13,6 @@ Ice.__M.require(module,
"../Ice/Class",
"../Ice/ArrayUtil",
"../Ice/AsyncResult",
- "../Ice/ConnectRequestHandler",
"../Ice/Debug",
"../Ice/FormatType",
"../Ice/HashMap",
@@ -29,7 +28,6 @@ Ice.__M.require(module,
var ArrayUtil = Ice.ArrayUtil;
var AsyncResultBase = Ice.AsyncResultBase;
var AsyncResult = Ice.AsyncResult;
-var ConnectRequestHandler = Ice.ConnectRequestHandler;
var Debug = Ice.Debug;
var FormatType = Ice.FormatType;
var HashMap = Ice.HashMap;
@@ -540,14 +538,14 @@ var ObjectPrx = Ice.Class({
{
return this._requestHandler;
}
- this._requestHandler = new ConnectRequestHandler(this._reference, this);
- handler = this._requestHandler;
+ handler = this._reference.getInstance().requestHandlerFactory().getRequestHandler(this._reference, this);
+ this._requestHandler = handler;
}
else
{
- handler = new ConnectRequestHandler(this._reference, this);
+ handler = this._reference.getInstance().requestHandlerFactory().getRequestHandler(this._reference, this);
}
- return handler.connect();
+ return handler.connect(this);
},
__setRequestHandler: function(previous, handler)
{
diff --git a/js/src/Ice/Operation.js b/js/src/Ice/Operation.js
index 0fc4db50335..e11f377ada1 100644
--- a/js/src/Ice/Operation.js
+++ b/js/src/Ice/Operation.js
@@ -376,7 +376,6 @@ var __dispatchImpl = function(servant, op, incomingAsync, current)
var comm = current.adapter.getCommunicator();
var msg = "servant for identity " + comm.identityToString(current.id) +
" does not define operation `" + op.servantMethod + "'";
- console.log(msg);
throw new Ice.UnknownException(msg);
}
diff --git a/js/src/Ice/Promise.js b/js/src/Ice/Promise.js
index de0a2ce2bfe..326611c0f57 100644
--- a/js/src/Ice/Promise.js
+++ b/js/src/Ice/Promise.js
@@ -142,13 +142,10 @@ var Promise = Ice.Class({
};
};
- setTimeout(
- function()
- {
- self.then(delayHandler(p, p.succeed),
- delayHandler(p, p.fail));
- });
-
+ setTimeout(function()
+ {
+ self.then(delayHandler(p, p.succeed), delayHandler(p, p.fail));
+ });
return p;
},
resolve: function()
diff --git a/js/src/Ice/RequestHandlerFactory.js b/js/src/Ice/RequestHandlerFactory.js
new file mode 100644
index 00000000000..58c63aa339b
--- /dev/null
+++ b/js/src/Ice/RequestHandlerFactory.js
@@ -0,0 +1,60 @@
+// **********************************************************************
+//
+// 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.
+//
+// **********************************************************************
+
+var Ice = require("../Ice/ModuleRegistry").Ice;
+Ice.__M.require(module,
+ [
+ "../Ice/Class",
+ "../Ice/Debug",
+ "../Ice/HashMap",
+ "../Ice/Reference",
+ "../Ice/ConnectRequestHandler"
+ ]);
+
+var Debug = Ice.Debug;
+var HashMap = Ice.HashMap;
+var ConnectRequestHandler = Ice.ConnectRequestHandler;
+
+var RequestHandlerFactory = Ice.Class({
+ __init__: function(instance)
+ {
+ this._instance = instance;
+ this._handlers = new HashMap();
+ this._handlers.keyComparator = HashMap.compareEquals;
+ },
+ getRequestHandler: function(ref, proxy)
+ {
+ if(ref.getCacheConnection())
+ {
+ var handler = this._handlers.get(ref);
+ if(handler)
+ {
+ return handler;
+ }
+ handler = new ConnectRequestHandler(ref, proxy);
+ this._handlers.set(ref, handler);
+ return handler;
+ }
+ else
+ {
+ return new ConnectRequestHandler(ref, proxy);
+ }
+ },
+ removeRequestHandler: function(ref, handler)
+ {
+ if(ref.getCacheConnection())
+ {
+ var h = this._handlers.delete(ref);
+ Debug.assert(h === handler);
+ }
+ }
+});
+
+Ice.RequestHandlerFactory = RequestHandlerFactory;
+module.exports.Ice = Ice;
diff --git a/js/test/Common/TestSuite.js b/js/test/Common/TestSuite.js
index 04f10bf864c..a3e9e5fd85e 100644
--- a/js/test/Common/TestSuite.js
+++ b/js/test/Common/TestSuite.js
@@ -89,7 +89,7 @@ $(document).foundation();
},
function(ex)
{
- out.writeLine("failed! (" + ex.ice_name() + ")");
+ out.writeLine("failed! (" + ex + ")");
return __test__(out, id);
}
).then(
diff --git a/js/test/Common/index.html b/js/test/Common/index.html
index 976452c9b31..80bb50eec7f 100644
--- a/js/test/Common/index.html
+++ b/js/test/Common/index.html
@@ -120,6 +120,7 @@
"../exceptions/Client.js", "Client.js"],
"Ice/facets": ["Test.js", "Client.js"],
"Ice/facetsBidir": ["Test.js", "TestI.js", "../facets/Client.js", "Client.js"],
+ "Ice/hold": ["Test.js", "Client.js"],
"Ice/inheritance": ["Test.js", "Client.js"],
"Ice/inheritanceBidir": ["Test.js", "InitialI.js", "../inheritance/Client.js", "Client.js"],
"Ice/operations": ["Test.js", "Twoways.js", "Oneways.js", "BatchOneways.js", "Client.js"],
diff --git a/js/test/Ice/Makefile b/js/test/Ice/Makefile
index 69dc0d5a4f2..fd3d9c6a5d2 100644
--- a/js/test/Ice/Makefile
+++ b/js/test/Ice/Makefile
@@ -21,6 +21,7 @@ SUBDIRS = \
exceptionsBidir \
facets \
facetsBidir \
+ hold \
inheritance \
inheritanceBidir \
location \
diff --git a/js/test/Ice/Makefile.mak b/js/test/Ice/Makefile.mak
index 16475a3cd81..7738c58073b 100644
--- a/js/test/Ice/Makefile.mak
+++ b/js/test/Ice/Makefile.mak
@@ -21,6 +21,7 @@ SUBDIRS = \
exceptionsBidir \
facets \
facetsBidir \
+ hold \
inheritance \
inheritanceBidir \
location \
diff --git a/js/test/Ice/hold/.depend.mak b/js/test/Ice/hold/.depend.mak
new file mode 100644
index 00000000000..a3b320ad9c2
--- /dev/null
+++ b/js/test/Ice/hold/.depend.mak
@@ -0,0 +1,3 @@
+
+Test.js: \
+ .\Test.ice
diff --git a/js/test/Ice/hold/.gitignore b/js/test/Ice/hold/.gitignore
new file mode 100644
index 00000000000..d158d9308ba
--- /dev/null
+++ b/js/test/Ice/hold/.gitignore
@@ -0,0 +1,2 @@
+Test.js
+index.html
diff --git a/js/test/Ice/hold/Client.js b/js/test/Ice/hold/Client.js
new file mode 100644
index 00000000000..dd8ca258cc9
--- /dev/null
+++ b/js/test/Ice/hold/Client.js
@@ -0,0 +1,307 @@
+// **********************************************************************
+//
+// 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(module, require, exports)
+{
+ var Ice = require("icejs").Ice;
+ var Test = require("Test").Test;
+ var Promise = Ice.Promise;
+
+ function loop(fn, repetitions, condition)
+ {
+ var i = 0;
+ var next = function()
+ {
+ while(i++ < repetitions && (!condition || condition.value))
+ {
+ var r = fn.call(i);
+ if(r)
+ {
+ return r.then(next);
+ }
+ }
+ };
+ return next();
+ }
+
+ var allTests = function(out, communicator)
+ {
+ var failCB = function() { test(false); };
+ var hold, holdOneway, holdSerialized, holdSerializedOneway;
+ var condition = { value: true };
+ var value = 0;
+
+ var p = new Promise();
+ var test = function(b)
+ {
+ if(!b)
+ {
+ try
+ {
+ throw new Error("test failed");
+ }
+ catch(err)
+ {
+ p.fail(err);
+ throw err;
+ }
+ }
+ };
+
+ var seq;
+ Promise.try(
+ function()
+ {
+ var ref = "hold:default -p 12010";
+ return Test.HoldPrx.checkedCast(communicator.stringToProxy(ref));
+ }
+ ).then(
+ function(obj)
+ {
+ test(obj !== null);
+ hold = obj;
+ holdOneway = Test.HoldPrx.uncheckedCast(hold.ice_oneway());
+
+ var refSerialized = "hold:default -p 12011";
+ return Test.HoldPrx.checkedCast(communicator.stringToProxy(refSerialized));
+ }
+ ).then(
+ function(obj)
+ {
+ test(obj !== null);
+ holdSerialized = obj;
+ holdSerializedOneway = Test.HoldPrx.uncheckedCast(holdSerialized.ice_oneway());
+
+ out.write("changing state between active and hold rapidly... ");
+
+ var i;
+ var r = new Ice.Promise().succeed();
+ for(i = 0; i < 1; ++i)
+ {
+ r = r.then(function() { return hold.putOnHold(0); });
+ }
+ for(i = 0; i < 1; ++i)
+ {
+ r = r.then(function() { return holdOneway.putOnHold(0); });
+ }
+ for(i = 0; i < 1; ++i)
+ {
+ r = r.then(function() { return holdSerialized.putOnHold(0); });
+ }
+ for(i = 0; i < 1; ++i)
+ {
+ r = r.then(function() { return holdSerializedOneway.putOnHold(0); });
+ }
+ return r;
+ }
+ ).then(
+ function()
+ {
+ out.writeLine("ok");
+
+ out.write("testing without serialize mode... ");
+ var result = null;
+ condition.value = true;
+ return loop(function()
+ {
+ var expected = value;
+ var result = hold.set(value + 1, 3).then(function(v)
+ {
+ condition.value = (v == expected);
+ });
+ ++value;
+ if(value % 100 === 0)
+ {
+ return result;
+ }
+ return null;
+ }, 100000, condition);
+ }
+ ).then(
+ function()
+ {
+ test(!condition.value);
+ out.writeLine("ok");
+
+ out.write("testing with serialize mode... ");
+
+ condition.value = true;
+ var result;
+ return loop(
+ function()
+ {
+ var expected = value;
+ result = holdSerialized.set(value + 1, 1).then(function(v)
+ {
+ condition.value = (v == expected);
+ });
+ ++value;
+ if(value % 100 === 0)
+ {
+ return result;
+ }
+ return null;
+ }, 1000, condition);
+ }
+ ).then(
+ function()
+ {
+ test(condition.value);
+ return loop(function()
+ {
+ holdSerializedOneway.setOneway(value + 1, value);
+ ++value;
+ if((value % 100) === 0)
+ {
+ holdSerializedOneway.putOnHold(1);
+ }
+ }, 3000);
+ }
+ ).then(
+ function()
+ {
+ out.writeLine("ok");
+
+ out.write("testing serialization... ");
+
+ condition.value = true;
+ value = 0;
+ return holdSerialized.set(value, 0);
+ }
+ ).then(
+ function()
+ {
+ return loop(
+ function()
+ {
+ // Create a new proxy for each request
+ var result = holdSerialized.ice_oneway().setOneway(value + 1, value);
+ ++value;
+ if((value % 100) === 0)
+ {
+ return result.then(function()
+ {
+ return holdSerialized.ice_getConnection().then(
+ function(con)
+ {
+ return con.close(false);
+ });
+ });
+ }
+ return null;
+ }, 1000);
+ }
+ ).then(
+ function()
+ {
+ out.writeLine("ok");
+
+ out.write("testing waitForHold... ");
+
+ return hold.waitForHold().then(
+ function()
+ {
+ return hold.waitForHold();
+ }
+ ).then(
+ function()
+ {
+ return loop(function(i)
+ {
+ var r = hold.ice_oneway().ice_ping();
+ if((i % 20) == 0)
+ {
+ r = r.then(function() { return hold.putOnHold(0); })
+ }
+ return r;
+ }, 100);
+ }
+ ).then(
+ function()
+ {
+ return hold.putOnHold(-1);
+ }
+ ).then(
+ function()
+ {
+ return hold.ice_ping();
+ }
+ ).then(
+ function()
+ {
+ return hold.putOnHold(-1);
+ }
+ ).then(
+ function()
+ {
+ return hold.ice_ping();
+ }
+ );
+ }
+ ).then(
+ function()
+ {
+ out.writeLine("ok");
+
+ out.write("changing state to hold and shutting down server... ");
+ return hold.shutdown();
+ }
+ ).then(
+ function()
+ {
+ out.writeLine("ok");
+ p.succeed();
+ },
+ function(ex)
+ {
+ out.writeLine("failed!");
+ p.fail(ex);
+ });
+ return p;
+ };
+
+ var run = function(out, id)
+ {
+ //
+ // For this test, we want to disable retries.
+ //
+ id.properties.setProperty("Ice.RetryIntervals", "-1");
+
+ //
+ // We don't want connection warnings because of the timeout
+ //
+ id.properties.setProperty("Ice.Warn.Connections", "0");
+
+ //
+ // We need to send messages large enough to cause the transport
+ // buffers to fill up.
+ //
+ id.properties.setProperty("Ice.MessageSizeMax", "10000");
+
+ id.properties.setProperty("Ice.RetryIntervals", "-1");
+
+ var c = Ice.initialize(id);
+ return Promise.try(
+ function()
+ {
+ return allTests(out, c);
+ }
+ ).finally(
+ function()
+ {
+ return c.destroy();
+ }
+ );
+ };
+ exports.__test__ = run;
+ exports.__runServer__ = true;
+}
+(typeof(global) !== "undefined" && typeof(global.process) !== "undefined" ? module : undefined,
+ typeof(global) !== "undefined" && typeof(global.process) !== "undefined" ? require : window.Ice.__require,
+ typeof(global) !== "undefined" && typeof(global.process) !== "undefined" ? exports : window));
diff --git a/js/test/Ice/hold/Makefile b/js/test/Ice/hold/Makefile
new file mode 100644
index 00000000000..8f81ea44140
--- /dev/null
+++ b/js/test/Ice/hold/Makefile
@@ -0,0 +1,23 @@
+# **********************************************************************
+#
+# 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.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+TARGETS = index.html
+
+SLICES = Test.ice
+
+GEN_SRCS = $(patsubst %.ice, %.js, $(SLICES))
+
+SRCS = Client.js
+
+include $(top_srcdir)/config/Make.rules.js
+
+SLICE2JSFLAGS := $(SLICE2JSFLAGS) -I$(slicedir)
+
diff --git a/js/test/Ice/hold/Makefile.mak b/js/test/Ice/hold/Makefile.mak
new file mode 100644
index 00000000000..61a62482429
--- /dev/null
+++ b/js/test/Ice/hold/Makefile.mak
@@ -0,0 +1,20 @@
+# **********************************************************************
+#
+# 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+TARGETS = index.html
+
+GEN_SRCS = Test.js
+
+SRCS = Client.js
+
+!include $(top_srcdir)\config\Make.rules.mak.js
+
+SLICE2JSFLAGS = $(SLICE2JSFLAGS) -I"$(slicedir)"
diff --git a/js/test/Ice/hold/Test.ice b/js/test/Ice/hold/Test.ice
new file mode 100644
index 00000000000..dc7f1dbe67f
--- /dev/null
+++ b/js/test/Ice/hold/Test.ice
@@ -0,0 +1,24 @@
+// **********************************************************************
+//
+// 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.
+//
+// **********************************************************************
+
+#pragma once
+
+module Test
+{
+
+interface Hold
+{
+ void putOnHold(int seconds);
+ void waitForHold();
+ void setOneway(int value, int expected);
+ int set(int value, int delay);
+ void shutdown();
+};
+
+};
diff --git a/js/test/Ice/hold/run.js b/js/test/Ice/hold/run.js
new file mode 100644
index 00000000000..8a86aa5886f
--- /dev/null
+++ b/js/test/Ice/hold/run.js
@@ -0,0 +1,10 @@
+// **********************************************************************
+//
+// 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.
+//
+// **********************************************************************
+
+require("../../Common/Common").run(module);
diff --git a/js/test/Ice/hold/run.py b/js/test/Ice/hold/run.py
new file mode 100755
index 00000000000..ee3bc52bf23
--- /dev/null
+++ b/js/test/Ice/hold/run.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# **********************************************************************
+#
+# 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.
+#
+# **********************************************************************
+
+import os, sys
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()