summaryrefslogtreecommitdiff
path: root/js/demo/Ice/throughput
diff options
context:
space:
mode:
Diffstat (limited to 'js/demo/Ice/throughput')
-rw-r--r--js/demo/Ice/throughput/.gitignore1
-rw-r--r--js/demo/Ice/throughput/Client.js397
-rw-r--r--js/demo/Ice/throughput/Makefile16
-rw-r--r--js/demo/Ice/throughput/Makefile.mak16
-rw-r--r--js/demo/Ice/throughput/README26
-rw-r--r--js/demo/Ice/throughput/Throughput.ice63
-rw-r--r--js/demo/Ice/throughput/browser/Client.js345
-rw-r--r--js/demo/Ice/throughput/build.js10
-rwxr-xr-xjs/demo/Ice/throughput/expect.py30
-rw-r--r--js/demo/Ice/throughput/index.html181
10 files changed, 1085 insertions, 0 deletions
diff --git a/js/demo/Ice/throughput/.gitignore b/js/demo/Ice/throughput/.gitignore
new file mode 100644
index 00000000000..6e8a0fb4232
--- /dev/null
+++ b/js/demo/Ice/throughput/.gitignore
@@ -0,0 +1 @@
+Throughput.js
diff --git a/js/demo/Ice/throughput/Client.js b/js/demo/Ice/throughput/Client.js
new file mode 100644
index 00000000000..20d0bd1ddf4
--- /dev/null
+++ b/js/demo/Ice/throughput/Client.js
@@ -0,0 +1,397 @@
+// **********************************************************************
+//
+// 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(){
+
+require("Ice");
+require("./Throughput");
+
+function menu()
+{
+ process.stdout.write(
+ "usage:\n" +
+ "\n" +
+ "toggle type of data to send:\n" +
+ "1: sequence of bytes (default)\n" +
+ "2: sequence of strings (\"hello\")\n" +
+ "3: sequence of structs with a string (\"hello\") and a double\n" +
+ "4: sequence of structs with two ints and a double\n" +
+ "\n" +
+ "select test to run:\n" +
+ "t: Send sequence as twoway\n" +
+ "o: Send sequence as oneway\n" +
+ "r: Receive sequence\n" +
+ "e: Echo (send and receive) sequence\n" +
+ "\n" +
+ "other commands:\n" +
+ "s: shutdown server\n" +
+ "x: exit\n" +
+ "?: help\n" +
+ "\n");
+};
+
+//
+// Asynchronous loop, each call to the given function returns a
+// promise that when fulfilled runs the next iteration.
+//
+function loop(fn, repetitions)
+{
+ var i = 0;
+ var next = function()
+ {
+ if(i++ < repetitions)
+ {
+ return fn.call().then(next);
+ }
+ };
+ return next();
+}
+
+//
+// Initialize sequences.
+//
+var byteSeq = new Buffer(Demo.ByteSeqSize);
+for(var i = 0; i < Demo.ByteSeqSize; ++i)
+{
+ byteSeq[i] = 0;
+}
+
+var stringSeq = [];
+for(var i = 0; i < Demo.StringSeqSize; ++i)
+{
+ stringSeq[i] = "hello";
+}
+
+var structSeq = [];
+for(var i = 0; i < Demo.StringDoubleSeqSize; ++i)
+{
+ structSeq[i] = new Demo.StringDouble();
+ structSeq[i].s = "hello";
+ structSeq[i].d = 3.14;
+}
+
+var fixedSeq = [];
+for(var i = 0; i < Demo.FixedSeqSize; ++i)
+{
+ fixedSeq[i] = new Demo.Fixed();
+ fixedSeq[i].i = 0;
+ fixedSeq[i].j = 0;
+ fixedSeq[i].d = 0;
+}
+
+var communicator;
+Ice.Promise.try(
+ function()
+ {
+ var currentType = "1";
+ var repetitions = 100;
+
+ var seqSize = Demo.ByteSeqSize;
+ var seq = byteSeq;
+ var wireSize = 1;
+
+ //
+ // Initialize the communicator and create a proxy
+ // to the throughput object.
+ //
+ communicator = Ice.initialize();
+ var proxy = communicator.stringToProxy("throughput:default -p 10000");
+
+ //
+ // Down-cast the proxy to the Demo.Throughput interface.
+ //
+ return Demo.ThroughputPrx.checkedCast(proxy).then(
+ function(twoway)
+ {
+ var oneway = twoway.ice_oneway();
+ menu();
+ process.stdout.write("==> ");
+ var keyLoop = new Ice.Promise();
+
+ function processKey(key)
+ {
+ if(key == "x")
+ {
+ keyLoop.succeed();
+ return;
+ }
+
+ var proxy;
+ var operation;
+
+ if(key == "1" || key == "2" || key == "3" || key == "4")
+ {
+ currentType = key;
+
+ //
+ // Select the sequence data type to use by this test.
+ //
+ switch(currentType)
+ {
+ case "1":
+ {
+ console.log("using byte sequences");
+ seqSize = Demo.ByteSeqSize;
+ seq = byteSeq;
+ wireSize = 1;
+ break;
+ }
+
+ case "2":
+ {
+ console.log("using string sequences");
+ seqSize = Demo.StringSeqSize;
+ seq = stringSeq;
+ wireSize = seq[0].length;
+ break;
+ }
+
+ case "3":
+ {
+ console.log("using variable-length struct sequences");
+ seqSize = Demo.StringDoubleSeqSize;
+ seq = structSeq;
+ wireSize = seq[0].s.length;
+ wireSize += 8; // Size of double on the wire.
+ break;
+ }
+
+ case "4":
+ {
+ console.log("using fixed-length struct sequences");
+ seqSize = Demo.FixedSeqSize;
+ seq = fixedSeq;
+ wireSize = 16; // Size of two ints and a double on the wire.
+ break;
+ }
+ }
+ }
+ else if(key == "t" || key == "o" || key == "r" || key == "e")
+ {
+ //
+ // Select the proxy and operation to use by this test.
+ //
+ switch(key)
+ {
+ case "t":
+ case "o":
+ {
+ proxy = key == "o" ? oneway : twoway;
+ if(currentType == 1)
+ {
+ operation = proxy.sendByteSeq;
+ }
+ else if(currentType == 2)
+ {
+ operation = proxy.sendStringSeq;
+ }
+ else if(currentType == 3)
+ {
+ operation = proxy.sendStructSeq;
+ }
+ else if(currentType == 4)
+ {
+ operation = proxy.sendFixedSeq;
+ }
+ process.stdout.write("sending");
+ break;
+ }
+
+ case "r":
+ {
+ proxy = twoway;
+ if(currentType == 1)
+ {
+ operation = proxy.recvByteSeq;
+ }
+ else if(currentType == 2)
+ {
+ operation = proxy.recvStringSeq;
+ }
+ else if(currentType == 3)
+ {
+ operation = proxy.recvStructSeq;
+ }
+ else if(currentType == 4)
+ {
+ operation = proxy.recvFixedSeq;
+ }
+ process.stdout.write("receiving");
+ break;
+ }
+
+ case "e":
+ {
+ proxy = twoway;
+ if(currentType == 1)
+ {
+ operation = proxy.echoByteSeq;
+ }
+ else if(currentType == 2)
+ {
+ operation = proxy.echoStringSeq;
+ }
+ else if(currentType == 3)
+ {
+ operation = proxy.echoStructSeq;
+ }
+ else if(currentType == 4)
+ {
+ operation = proxy.echoFixedSeq;
+ }
+ process.stdout.write("sending and receiving");
+ break;
+ }
+ }
+
+ process.stdout.write(" " + repetitions);
+ switch(currentType)
+ {
+ case "1":
+ {
+ process.stdout.write(" byte");
+ break;
+ }
+ case "2":
+ {
+ process.stdout.write(" string");
+ break;
+ }
+ case "3":
+ {
+ process.stdout.write(" variable-length struct");
+ break;
+ }
+
+ case "4":
+ {
+ process.stdout.write(" fixed-length struct");
+ break;
+ }
+ }
+
+ process.stdout.write(" sequences of size " + seqSize);
+
+ if(key == "o")
+ {
+ process.stdout.write(" as oneway");
+ }
+ console.log("...");
+
+ var start = new Date().getTime();
+ var args = key != "r" ? [seq] : [];
+ return loop(
+ function()
+ {
+ return operation.apply(proxy, args);
+ },
+ repetitions
+ ).then(
+ function()
+ {
+ //
+ // Write the results.
+ //
+ var total = new Date().getTime() - start;
+ console.log("time for " + repetitions + " sequences: " + total + " ms");
+ console.log("time per sequence: " + total / repetitions + " ms");
+
+ var mbit = repetitions * seqSize * wireSize * 8.0 / total / 1000.0;
+ if(key == "e")
+ {
+ mbit *= 2;
+ }
+ mbit = Math.round(mbit * 100) / 100;
+ console.log("throughput: " + mbit + " Mbps");
+ });
+ }
+ else if(key == "s")
+ {
+ return twoway.shutdown();
+ process.stdout.write("==> ");
+ }
+ else if(key == "?")
+ {
+ process.stdout.write("\n");
+ menu();
+ }
+ else
+ {
+ console.log("unknown command `" + key + "'");
+ process.stdout.write("\n");
+ menu();
+ }
+ }
+
+ //
+ // Process keys sequentially. We chain the promise objects
+ // returned by processKey(). Once we have process all the
+ // keys we print the prompt and resume the standard input.
+ //
+ process.stdin.resume();
+ var promise = new Ice.Promise().succeed();
+ process.stdin.on("data",
+ function(buffer)
+ {
+ process.stdin.pause();
+ var data = buffer.toString("utf-8").trim().split("");
+ // Process each key
+ data.forEach(function(key)
+ {
+ promise = promise.then(
+ function(r)
+ {
+ return processKey(key);
+ }
+ ).exception(
+ function(ex)
+ {
+ console.log(ex.toString());
+ });
+ });
+ // Once we're done, print the prompt
+ promise.then(function()
+ {
+ if(!keyLoop.completed())
+ {
+ process.stdout.write("==> ");
+ process.stdin.resume();
+ }
+ });
+ data = [];
+ });
+
+ return keyLoop;
+ });
+ }
+).finally(
+ function()
+ {
+ //
+ // Destroy the communicator if required.
+ //
+ if(communicator)
+ {
+ return communicator.destroy();
+ }
+ }
+).then(
+ function()
+ {
+ process.exit(0);
+ },
+ function(ex)
+ {
+ //
+ // Handle any exceptions above.
+ //
+ console.log(ex.toString());
+ process.exit(1);
+ });
+}());
diff --git a/js/demo/Ice/throughput/Makefile b/js/demo/Ice/throughput/Makefile
new file mode 100644
index 00000000000..36cfcf309d4
--- /dev/null
+++ b/js/demo/Ice/throughput/Makefile
@@ -0,0 +1,16 @@
+# **********************************************************************
+#
+# 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 = Throughput.js
+
+include $(top_srcdir)/config/Make.rules.js
+
+SLICE2JSFLAGS := $(SLICE2JSFLAGS) -I$(slicedir)
diff --git a/js/demo/Ice/throughput/Makefile.mak b/js/demo/Ice/throughput/Makefile.mak
new file mode 100644
index 00000000000..47703ca9848
--- /dev/null
+++ b/js/demo/Ice/throughput/Makefile.mak
@@ -0,0 +1,16 @@
+# **********************************************************************
+#
+# 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 = Throughput.js
+
+!include $(top_srcdir)\config\Make.rules.mak.js
+
+SLICE2JSFLAGS = $(SLICE2JSFLAGS) -I"$(slicedir)"
diff --git a/js/demo/Ice/throughput/README b/js/demo/Ice/throughput/README
new file mode 100644
index 00000000000..c16a0436934
--- /dev/null
+++ b/js/demo/Ice/throughput/README
@@ -0,0 +1,26 @@
+A simple throughput demo that allows you to send sequences of various
+types between client and server and to measure the maximum bandwidth
+that can be achieved using serialized synchronous requests.
+
+To run the demo, first you need to start the Ice throughput server.
+This distribution includes server implementations in Python and C++,
+and each one has its own README file with instructions for starting
+the server. Please refer to the Python or C++ README in the
+appropriate demo subdirectory for more information.
+
+Note:
+
+ * To use the Python server you'll need a Python installation that is
+ compatible with the Ice for Python module included in Ice 3.5.1.
+
+ * To use the C++ server you'll need a C++ compiler compatible with
+ the Ice 3.5.1 C++ distribution.
+
+After starting the server, open a separate window and start the
+client:
+
+$ node Client.js
+
+The performance for byte sequences is expected to be greater than
+for other types because the cost of marshaling and unmarshaling is
+lower than for more complex types.
diff --git a/js/demo/Ice/throughput/Throughput.ice b/js/demo/Ice/throughput/Throughput.ice
new file mode 100644
index 00000000000..c2216a15bfc
--- /dev/null
+++ b/js/demo/Ice/throughput/Throughput.ice
@@ -0,0 +1,63 @@
+// **********************************************************************
+//
+// 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 Demo
+{
+
+sequence<byte> ByteSeq;
+const int ByteSeqSize = 500000;
+
+sequence<string> StringSeq;
+const int StringSeqSize = 50000;
+
+struct StringDouble
+{
+ string s;
+ double d;
+};
+sequence<StringDouble> StringDoubleSeq;
+const int StringDoubleSeqSize = 50000;
+
+struct Fixed
+{
+ int i;
+ int j;
+ double d;
+};
+sequence<Fixed> FixedSeq;
+const int FixedSeqSize = 50000;
+
+interface Throughput
+{
+ bool needsWarmup();
+ void startWarmup();
+ void endWarmup();
+
+ void sendByteSeq(ByteSeq seq);
+ ByteSeq recvByteSeq();
+ ByteSeq echoByteSeq(ByteSeq seq);
+
+ void sendStringSeq(StringSeq seq);
+ StringSeq recvStringSeq();
+ StringSeq echoStringSeq(StringSeq seq);
+
+ void sendStructSeq(StringDoubleSeq seq);
+ StringDoubleSeq recvStructSeq();
+ StringDoubleSeq echoStructSeq(StringDoubleSeq seq);
+
+ void sendFixedSeq(FixedSeq seq);
+ FixedSeq recvFixedSeq();
+ FixedSeq echoFixedSeq(FixedSeq seq);
+
+ void shutdown();
+};
+
+};
diff --git a/js/demo/Ice/throughput/browser/Client.js b/js/demo/Ice/throughput/browser/Client.js
new file mode 100644
index 00000000000..133481e3ea4
--- /dev/null
+++ b/js/demo/Ice/throughput/browser/Client.js
@@ -0,0 +1,345 @@
+// **********************************************************************
+//
+// 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(){
+
+var ThroughputPrx = Demo.ThroughputPrx;
+
+//
+// Initialize sequences.
+//
+var byteSeq = new ArrayBuffer();
+for(var i = 0; i < Demo.ByteSeqSize; ++i)
+{
+ byteSeq[i] = 0;
+}
+
+var stringSeq = [];
+for(var i = 0; i < Demo.StringSeqSize; ++i)
+{
+ stringSeq[i] = "hello";
+}
+
+var structSeq = [];
+for(var i = 0; i < Demo.StringDoubleSeqSize; ++i)
+{
+ structSeq[i] = new Demo.StringDouble();
+ structSeq[i].s = "hello";
+ structSeq[i].d = 3.14;
+}
+
+var fixedSeq = [];
+for(var i = 0; i < Demo.FixedSeqSize; ++i)
+{
+ fixedSeq[i] = new Demo.Fixed();
+ fixedSeq[i].i = 0;
+ fixedSeq[i].j = 0;
+ fixedSeq[i].d = 0;
+}
+
+var communicator = Ice.initialize();
+
+//
+// Run the throughput test.
+//
+function run()
+{
+ //
+ // Create a proxy to the throughput object.
+ //
+ var hostname = document.location.hostname || "127.0.0.1";
+ var secure = document.location.protocol.indexOf("https") != -1;
+ var ref = secure ?
+ "throughput:wss -h " + hostname + " -p 9090 -r /demowss" :
+ "throughput:ws -h " + hostname + " -p 8080 -r /demows";
+ var proxy = communicator.stringToProxy(ref);
+
+ //
+ // Down-cast the proxy to the Demo.Throughput interface.
+ //
+ return ThroughputPrx.checkedCast(proxy).then(
+ function(twoway)
+ {
+ oneway = twoway.ice_oneway();
+
+ var seq;
+ var seqSize
+ var wireSize;
+ var proxy;
+ var operation;
+ var repetitions = 100;
+
+ var data = $("#data").val();
+ //
+ // Get the sequence data
+ //
+ if(data == "byte-seq")
+ {
+ seq = byteSeq;
+ seqSize = Demo.ByteSeqSize;
+ seq = byteSeq;
+ wireSize = 1;
+ }
+ else if(data == "string-seq")
+ {
+ seq = stringSeq;
+ seqSize = Demo.StringSeqSize;
+ seq = stringSeq;
+ wireSize = seq[0].length;
+ }
+ else if(data == "struct-seq")
+ {
+ seq = structSeq;
+ seqSize = Demo.StringDoubleSeqSize;
+ seq = structSeq;
+ wireSize = seq[0].s.length;
+ //
+ // Size of double on the wire.
+ //
+ wireSize += 8;
+ }
+ else if(data == "fixed-seq")
+ {
+ seq = fixedSeq;
+ seqSize = Demo.FixedSeqSize;
+ seq = fixedSeq;
+ //
+ // Size of two ints and a double on the wire.
+ //
+ wireSize = 16;
+ }
+
+ //
+ // Get the proxy and operation
+ //
+ var test = $("#test").val();
+ if(test == "twoway" || test == "oneway")
+ {
+ proxy = test == "twoway" ? twoway : oneway;
+ if(data == "byte-seq")
+ {
+ operation = proxy.sendByteSeq;
+ }
+ else if(data == "string-seq")
+ {
+ operation = proxy.sendStringSeq;
+ }
+ else if(data == "struct-seq")
+ {
+ operation = proxy.sendStructSeq;
+ }
+ else if(data == "fixed-seq")
+ {
+ operation = proxy.sendFixedSeq;
+ }
+ write("sending");
+ }
+ else if(test == "receive")
+ {
+ proxy = twoway;
+ if(data == "byte-seq")
+ {
+ operation = proxy.recvByteSeq;
+ }
+ else if(data == "string-seq")
+ {
+ operation = proxy.recvStringSeq;
+ }
+ else if(data == "struct-seq")
+ {
+ operation = proxy.recvStructSeq;
+ }
+ else if(data == "fixed-seq")
+ {
+ operation = proxy.recvFixedSeq;
+ }
+ write("receiving");
+ }
+ else if(test == "echo")
+ {
+ proxy = twoway;
+ if(data == "byte-seq")
+ {
+ operation = proxy.echoByteSeq;
+ }
+ else if(data == "string-seq")
+ {
+ operation = proxy.echoStringSeq;
+ }
+ else if(data == "struct-seq")
+ {
+ operation = proxy.echoStructSeq;
+ }
+ else if(data == "fixed-seq")
+ {
+ operation = proxy.echoFixedSeq;
+ }
+ write("sending and receiving");
+ }
+
+ write(" " + repetitions);
+ if(data == "byte-seq")
+ {
+ write(" byte");
+ }
+ else if(data == "string-seq")
+ {
+ write(" string");
+ }
+ else if(data == "struct-seq")
+ {
+ write(" variable-length struct");
+ }
+ else if(data == "fixed-seq")
+ {
+ write(" fixed-length struct");
+ }
+ write(" sequences of size " + seqSize);
+ if(test == "oneway")
+ {
+ write(" as oneway");
+ }
+ writeLine("...");
+
+ //
+ // Invoke the test operation in a loop with the required
+ // arguments.
+ //
+ // We chain the promises. A test operation is called only
+ // once the promise for the previous operation is
+ // fulfilled.
+ //
+ var start = new Date().getTime();
+ var args = test != "receive" ? [seq] : [];
+ return loop(
+ function()
+ {
+ return operation.apply(proxy, args);
+ },
+ repetitions
+ ).then(
+ function()
+ {
+ //
+ // Write the results.
+ //
+ var total = new Date().getTime() - start;
+ writeLine("time for " + repetitions + " sequences: " + total + " ms");
+ writeLine("time per sequence: " + total / repetitions + " ms");
+
+ var mbit = repetitions * seqSize * wireSize * 8.0 / total / 1000.0;
+ if(test == "echo")
+ {
+ mbit *= 2;
+ }
+ mbit = Math.round(mbit * 100) / 100;
+ writeLine("throughput: " + mbit + " Mbps");
+ });
+ });
+}
+
+$("#run").click(
+ function()
+ {
+ //
+ // Run the throughput loop if not already running.
+ //
+ if(state !== State.Running)
+ {
+ setState(State.Running);
+
+ Ice.Promise.try(
+ function()
+ {
+ return run();
+ }
+ ).exception(
+ function(ex)
+ {
+ $("#output").val(ex.toString());
+ }
+ ).finally(
+ function()
+ {
+ setState(State.Idle);
+ }
+ );
+ }
+ return false;
+ });
+
+//
+// Asynchronous loop: each call to the given function returns a
+// promise that when fulfilled runs the next iteration.
+//
+function loop(fn, repetitions)
+{
+ var i = 0;
+ var next = function()
+ {
+ if(i++ < repetitions)
+ {
+ return fn.call().then(next);
+ }
+ };
+ return next();
+}
+
+//
+// Helper functions to write the output.
+//
+function write(msg)
+{
+ $("#output").val($("#output").val() + msg);
+}
+
+function writeLine(msg)
+{
+ write(msg + "\n");
+ $("#output").scrollTop($("#output").get(0).scrollHeight);
+}
+
+//
+// Handle the client state.
+//
+var State = {
+ Idle:0,
+ Running: 1
+};
+var state;
+
+function setState(s, ex)
+{
+ if(s != state)
+ {
+ switch(s)
+ {
+ case State.Running:
+ {
+ $("#output").val("");
+ $("#run").addClass("disabled");
+ $("#progress").show();
+ $("body").addClass("waiting");
+ break;
+ }
+ case State.Idle:
+ {
+ $("#run").removeClass("disabled");
+ $("#progress").hide();
+ $("body").removeClass("waiting");
+ break;
+ }
+ }
+ state = s;
+ }
+}
+
+setState(State.Idle);
+
+}());
diff --git a/js/demo/Ice/throughput/build.js b/js/demo/Ice/throughput/build.js
new file mode 100644
index 00000000000..160797dafcf
--- /dev/null
+++ b/js/demo/Ice/throughput/build.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 ("../../../config/build").build(__dirname, ["Throughput.ice"]);
diff --git a/js/demo/Ice/throughput/expect.py b/js/demo/Ice/throughput/expect.py
new file mode 100755
index 00000000000..c134c708034
--- /dev/null
+++ b/js/demo/Ice/throughput/expect.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# 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 sys, os
+
+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, "demoscript")) ]
+if len(path) == 0:
+ raise RuntimeError("can't find toplevel directory!")
+sys.path.append(path[0])
+
+from demoscript import Util
+from demoscript.Ice import throughput
+
+server = Util.spawn('./server --Ice.PrintAdapterReady', Util.getMirrorDir("cpp"), mapping="cpp")
+server.expect('.* ready')
+
+client = Util.spawn('node Client.js')
+
+throughput.run(client, server)
diff --git a/js/demo/Ice/throughput/index.html b/js/demo/Ice/throughput/index.html
new file mode 100644
index 00000000000..890c900c1f9
--- /dev/null
+++ b/js/demo/Ice/throughput/index.html
@@ -0,0 +1,181 @@
+<!doctype html>
+<html class="no-js" lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Throughput Demo | Ice for JavaScript</title>
+ <!-- Bundle with all the stylesheets used to build the user interface,
+ see assets/Makefile in your distribution for details -->
+ <link rel="stylesheet" type="text/css" href="../../../assets/common.css" />
+ <link rel="icon" type="image/x-icon" href="../../../assets/favicon.ico">
+ </head>
+ <body>
+ <!-- Header section that contains title and navigation bar -->
+ <section id="header">
+ <nav class="top-bar" data-topbar>
+ <ul class="title-area">
+ <li class="name">
+ <h1><a href="../../../index.html">Ice for JavaScript</a></h1>
+ </li>
+ <li class="toggle-topbar menu-icon"><a href="#">Menu</a></li>
+ </ul>
+ <section class="top-bar-section">
+ <!-- Right Nav Section -->
+ <ul class="right">
+ <li class="divider"></li>
+ <li><a href="#" id="viewReadme">Readme</a></li>
+ <li><a href="#" id="viewSource">Source</a></li>
+ </ul>
+ </section>
+ </nav>
+ <ul class="breadcrumbs">
+ <li><a href="../../../index.html">Ice</a></li>
+ <li><a href="../../index.html">Demos</a></li>
+ <li class="current"><a href="#">Throughput</a></li>
+ </ul>
+ </section>
+ <!-- Main section that contains the user interface -->
+ <section role="main" id="body">
+ <div class="row">
+ <div class="large-12 medium-12 columns">
+ <form>
+ <div class="row">
+ <div class="small-3 columns">
+ <label class="right inline" for="data">Data:</label>
+ </div>
+ <div class="small-9 columns">
+ <select id="data">
+ <option value="byte-seq">sequence of bytes (default)</option>
+ <option value="string-seq">sequence of strings ("hello")</option>
+ <option value="struct-seq">sequence of structs with a string ("hello") and a double</option>
+ <option value="fixed-seq">sequence of structs with two ints and a double</option>
+ </select>
+ </div>
+ </div>
+ <div class="row">
+ <div class="small-3 columns">
+ <label class="right inline" for="test">Test:</label>
+ </div>
+ <div class="small-9 columns">
+ <select id="test">
+ <option value="twoway">Send sequence as twoway</option>
+ <option value="oneway">Send sequence as oneway</option>
+ <option value="receive">Receive sequence</option>
+ <option value="echo">Echo (send and receive) sequence</option>
+ </select>
+ </div>
+ </div>
+ <div class="row">
+ <div class="small-12 columns">
+ <a href="#" class="button small" id="run">Run</a>
+ </div>
+ </div>
+ <div class="row">
+ <div class="small-12 columns">
+ <textarea id="output" class="disabled" readonly></textarea>
+ </div>
+ </div>
+ <div id="progress" class="row hide">
+ <div class="small-12 columns left">
+ <div class="inline left icon"></div>
+ <div class="text">Running...</div>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </section>
+ <!-- Modal dialog to show the client README -->
+ <div id="readme-modal" class="reveal-modal medium" data-reveal>
+ <h4>Throughput Demo Readme</h4>
+ <hr/>
+ <p>A simple throughput demo that allows you to send sequences of various
+ types between client and server and to measure the maximum bandwidth
+ that can be achieved using serialized synchronous requests.</p>
+
+ <p>To run the demo, first you need to start the Ice throughput server. This
+ distribution includes server implementations in Python and C++, and
+ each one has its own README file with instructions for starting the
+ server. Please refer to the Python or C++ README in the appropriate
+ demo subdirectory for more information.
+ </p>
+
+ <div class="panel callout radius">
+ <ul>
+ <li>To use the Python server you'll need a Python installation that is
+ compatible with the Ice for Python module included in Ice 3.5.1.</li>
+
+ <li>To use the C++ server you'll need a C++ compiler compatible with your
+ Ice for JavaScript distribution.</li>
+ </ul>
+ </div>
+
+ <p>You can change the data type using the <strong>"Data"</strong> select
+ box. The <strong>"Test"</strong> select box allows you to select which test
+ to run.</p>
+
+ <p>Then you can use the <strong>"Run"</strong> button to run this client.</p>
+
+ <div class="panel callout radius">
+ <p>The performance for byte sequences is expected to be greater than
+ for other types because the cost of marshaling and unmarshaling is
+ lower than for more complex types.</p>
+ </div>
+
+ <div class="panel callout radius">
+ <p>The client is configured to use WSS secure endpoints when the page
+ is loaded over HTTPS and WS unsecure endpoints when loaded over HTTP.</p>
+ </div>
+ <a class="close-reveal-modal">&#215;</a>
+ </div>
+ <!-- Modal dialog to show the client source code -->
+ <div id="source-modal" class="reveal-modal" data-reveal>
+ <a class="close-reveal-modal">&#215;</a>
+ <dl class="tabs" data-tab>
+ <dt></dt>
+ <dd class="active"><a href="#panel2-1">Slice</a></dd>
+ <dd><a href="#panel2-2">JavaScript</a></dd>
+ <dd><a href="#panel2-3">HTML</a></dd>
+ </dl>
+ <div class="tabs-content">
+ <div class="content active" id="panel2-1">
+ <h6>File: Ice/throughput/Throughput.ice</h6>
+ <pre class="source language-c" data-code="Throughput.ice"></pre>
+ </div>
+ <div class="content" id="panel2-2">
+ <h6>File: Ice/throughput/browser/Client.js</h6>
+ <pre class="source" data-code="browser/Client.js"></pre>
+ </div>
+ <div class="content" id="panel2-3">
+ <h6>File: Ice/throughput/index.html</h6>
+ <pre class="source" data-code="index.html"></pre>
+ </div>
+ </div>
+ </div>
+ <!-- Footer section -->
+ <section id="footer">
+ <div class="logo">
+ <h4><strong>ZeroC</strong></h4>
+ </div>
+ <div class="copyright">
+ <h6>© 2014 ZeroC, Inc. All rights reserved.</h6>
+ </div>
+ </section>
+ <!-- Bundle with all the scripts used to build the user interface,
+ see assets/Makefile in your distribution for details -->
+ <script type="text/javascript" src="../../../assets/common.min.js"></script>
+ <!-- Ice.js (Ice run-time library) -->
+ <script type="text/javascript" src="../../../lib/Ice.js"></script>
+ <!-- Throughput.js (Demo generated code) -->
+ <script type="text/javascript" src="Throughput.js"></script>
+ <!-- browser/Client.js (Throughput Demo Application) -->
+ <script type="text/javascript" src="browser/Client.js"></script>
+
+ <script type="text/javascript">
+ if(["http:", "https:"].indexOf(document.location.protocol) !== -1)
+ {
+ checkGenerated(["Throughput.js"]);
+ }
+ </script>
+ </body>
+</html>