r9656 - in helma-ng/trunk: apps/demo apps/demo/skins modules/helma/webapp
[email protected] Wed, 22 Apr 2009 15:10:07 +0200 (CEST)
| Newsgroups | gmane.comp.java.helma.cvs |
|---|---|
| Message-ID | <20090422131007.B2B0A3D0D6@mia> |
Author: hannes
Date: 2009-04-22 15:10:07 +0200 (Wed, 22 Apr 2009)
New Revision: 9656
Modified:
helma-ng/trunk/apps/demo/actions.js
helma-ng/trunk/apps/demo/skins/continuation.html
helma-ng/trunk/modules/helma/webapp/continuation.js
Log:
Rewrite continuation support once again. Starting to look usable.
Details at http://dev.helma.org/trac/helma/changeset/9656
Modified: helma-ng/trunk/apps/demo/actions.js
===================================================================
--- helma-ng/trunk/apps/demo/actions.js 2009-04-22 13:10:04 UTC (rev 9655)
+++ helma-ng/trunk/apps/demo/actions.js 2009-04-22 13:10:07 UTC (rev 9656)
@@ -46,49 +46,41 @@
// local data - this is the data that is shared between continuations of this function
var data = {};
+ var session = new ContinuationSession("welcome", "ask_name", "ask_food", "ask_animal", "result");
+ req = session.start(req);
- req = ContinuationMark(req, "welcome");
-
// render intro page
- req = ContinuationRequest(req, "ask_name", SkinnedResponse('skins/continuation.html', {
- skin: "welcome",
+ req = session.step(1).render(req, SkinnedResponse('skins/continuation.html', {
+ session: session,
title: "Continuations Demo",
- data: data,
- forward: ContinuationUrl("ask_name")
+ data: data
}));
- req = ContinuationRequest(req, "ask_food", SkinnedResponse('skins/continuation.html', {
- skin: "ask_name",
+ req = session.step(2).render(req, SkinnedResponse('skins/continuation.html', {
+ session: session,
title: "Question 1",
- data: data,
- back: ContinuationUrl("welcome"),
- forward: ContinuationUrl("ask_food")
+ data: data
}));
data.name = req.params.name || data.name;
- req = ContinuationRequest(req, "ask_animal", SkinnedResponse('skins/continuation.html', {
- skin: "ask_food",
+ req = session.step(3).render(req, SkinnedResponse('skins/continuation.html', {
+ session: session,
title: "Question 2",
- data: data,
- back: ContinuationUrl("ask_name"),
- forward: ContinuationUrl("ask_animal")
+ data: data
}));
data.food = req.params.food || data.food;
- req = ContinuationRequest(req, "result", SkinnedResponse('skins/continuation.html', {
- skin: "ask_animal",
+ req = session.step(4).render(req, SkinnedResponse('skins/continuation.html', {
+ session: session,
title: "Question 3",
- data: data,
- back: ContinuationUrl("ask_food"),
- forward: ContinuationUrl("result")
+ data: data
}));
data.animal = req.params.animal || data.animal;
- return SkinnedResponse('skins/continuation.html', {
- skin: "result",
+ session.step(5).render(req, SkinnedResponse('skins/continuation.html', {
+ session: session,
title: "Thank you!",
- data: data,
- back: ContinuationUrl("ask_animal")
- });
+ data: data
+ }));
}
\ No newline at end of file
Modified: helma-ng/trunk/apps/demo/skins/continuation.html
===================================================================
--- helma-ng/trunk/apps/demo/skins/continuation.html 2009-04-22 13:10:04 UTC (rev 9655)
+++ helma-ng/trunk/apps/demo/skins/continuation.html 2009-04-22 13:10:07 UTC (rev 9656)
@@ -1,7 +1,7 @@
<% extends 'base.html' %>
<% subskin 'content' -------------------------------------------------------------------- %>
-<% render <% skin %> %>
+<% render <% session.page %> %>
<% subskin 'welcome' %>
@@ -10,7 +10,7 @@
<p>This is a little game to show off continuations support in Helma NG.
All you'll have to do is answer a few easy questions.</p>
- <p><a href="<% forward %>">start</a></p>
+ <p><a href="<% session.forward %>">start</a></p>
<p>What's special about this demo is that all pages are generated by
one JavaScript function which is run only once, but resumed and suspended
@@ -22,34 +22,34 @@
<% subskin 'ask_name' %>
- What is your name? <form method="post" action="<% forward %>">
+ What is your name? <form method="post" action="<% session.forward %>">
<input name="name" value="<% data.name %>">
<input type="submit">
</form>
- <p><a href="<% back %>">back</a> <a href="<% forward %>">forward</a></p>
+ <p><a href="<% session.back %>">back</a> <a href="<% session.forward %>">forward</a></p>
<% render 'list' %>
<% subskin 'ask_food' %>
- What is your favorite food? <form method="post" action="<% forward %>">
+ What is your favorite food? <form method="post" action="<% session.forward %>">
<input name="food" value="<% data.food %>">
<input type="submit">
</form>
- <p><a href="<% back %>">back</a> <a href="<% forward %>">forward</a></p>
+ <p><a href="<% session.back %>">back</a> <a href="<% session.forward %>">forward</a></p>
<% render 'list' %>
<% subskin 'ask_animal' %>
- What is your favorite animal? <form method="post" action="<% forward %>">
+ What is your favorite animal? <form method="post" action="<% session.forward %>">
<input name="animal" value="<% data.animal %>">
<input type="submit">
</form>
- <p><a href="<% back %>">back</a> <a href="<% forward %>">forward</a></p>
+ <p><a href="<% session.back %>">back</a> <a href="<% session.forward %>">forward</a></p>
<% render 'list' %>
@@ -59,7 +59,7 @@
you love to eat <b><% data.food %></b> and your favorite animal
is <b><% data.animal %></b>.
- <p><a href="<% back %>">back</a></p>
+ <p><a href="<% session.back %>">back</a></p>
<% render 'list' %>
Modified: helma-ng/trunk/modules/helma/webapp/continuation.js
===================================================================
--- helma-ng/trunk/modules/helma/webapp/continuation.js 2009-04-22 13:10:04 UTC (rev 9655)
+++ helma-ng/trunk/modules/helma/webapp/continuation.js 2009-04-22 13:10:07 UTC (rev 9656)
@@ -2,70 +2,94 @@
* Continuation support for Helma NG
*/
-include('helma/webapp/response');
+export('ContinuationSession', 'handleRequest');
+
var system = require('helma/system');
+var log = require('helma/logging').getLogger(__name__);
-export('handleRequest', "ContinuationMark", "ContinuationRequest", "ContinuationUrl", "ContinuationId");
+var __shared__ = true;
-var log = require('helma/logging').getLogger(__name__);
+function ContinuationSession() {
+ var pages = [];
+ var ids = [];
+ var currentstep = 0;
+ for (var i = 0; i < arguments.length; i++) {
+ pages.push(arguments[i]);
+ }
+ var length = pages.length;
-var ids = {};
+ this.start = function(req) {
+ if (!req.params.helma_continuation) {
+ // set query param so helma knows to switch rhino optimization level to -1
+ throw { redirect: getContinuationUrl(0) };
+ }
+ if (system.getOptimizationLevel() > -1) {
+ system.setOptimizationLevel(-1);
+ throw { retry: true };
+ }
+ currentstep = 0;
+ ids[0] = id = req.params.helma_continuation;
+ var continuation = createContinuation();
+ if (continuation instanceof Continuation) {
+ log.debug("Recording continuation start: " + id);
+ setCallback(req, id, continuation);
+ return req;
+ } else {
+ return continuation;
+ }
+ };
-function ContinuationUrl(name) {
- return "?helma_continuation=" + ContinuationId(name);
-}
+ this.step = function(step) {
+ currentstep = step - 1;
+ return this;
+ };
-function ContinuationId(name) {
- if (!name)
- return generateId();
- if (!(name in ids))
- ids[name] = generateId();
- return ids[name];
-}
+ this.render = function(req, res) {
+ // capture continuation and store it in callback container
+ var id = getContinuationId(currentstep + 1);
+ var continuation = createContinuation();
+ if (continuation instanceof Continuation) {
+ if (!getCallback(req, id))
+ setCallback(req, id, continuation);
+ // Exit current js context by calling empty continuation with return value
+ new org.mozilla.javascript.NativeContinuation()(res);
+ } else {
+ return continuation;
+ }
+ };
-/**
- * Stop current execution and register continuation for later resumption.
- * @param id the continuation id. If not given a new id is generated.
- */
-function ContinuationRequest(req, name, res) {
- // capture continuation and store it in callback container
- var id = ContinuationId(name);
- var continuation = createContinuation();
- if (continuation instanceof Continuation) {
- log.debug("Registering continuation for id: " + id);
- setCallback(req, id, continuation);
- // Exit current js context by calling empty continuation with return value
- new org.mozilla.javascript.NativeContinuation()(res);
- } else {
- return continuation;
+ this.page = function() {
+ return pages[currentstep];
+ };
+
+ this.back = function() {
+ return currentstep > 0 ? getContinuationUrl(currentstep - 1) : null;
+ };
+
+ this.forward = function() {
+ return currentstep < length ? getContinuationUrl(currentstep + 1) : null;
+ };
+
+ function getContinuationUrl(step) {
+ return "?helma_continuation=" + getContinuationId(step);
}
-}
-function ContinuationMark(req, name) {
- if (!req.params.helma_continuation) {
- // set query param so helma knows to switch rhino optimization level to -1
- throw { redirect: ContinuationUrl() };
+ function getContinuationId(step) {
+ if (ids[step] == null) {
+ ids[step] = generateId();
+ }
+ return ids[step];
}
- if (system.getOptimizationLevel() > -1) {
- system.setOptimizationLevel(-1);
- throw { retry: true };
+
+ function createContinuation() {
+ return new Continuation();
}
- var id = req.params.helma_continuation;
- ids[name] = id;
- var continuation = createContinuation();
- if (continuation instanceof Continuation) {
- log.debug("Recording continuation start: " + id);
- setCallback(req, id, continuation);
- return req;
- } else {
- return continuation;
+
+ function generateId() {
+ return Math.ceil(Math.random() * Math.pow(2, 32)).toString(36);
}
}
-function createContinuation() {
- return new Continuation();
-}
-
/**
* Continuation middleware function
* @param req the request
@@ -85,16 +109,13 @@
return req.process();
}
-function generateId() {
- return Math.ceil(Math.random() * Math.pow(2, 32)).toString(36);
-}
-
var setCallback = function(req, id, func) {
if (!req.session.data.continuation) {
req.session.data.continuation = {};
}
log.debug("Registered continuation: " + id);
req.session.data.continuation[id] = func;
+ // fauxsessions[id] = func;
};
var getCallback = function(req, id) {
@@ -102,4 +123,8 @@
return null;
}
return req.session.data.continuation[id];
+ // return fauxsessions[id];
};
+
+// awful hack to make this work on google app engine
+// var fauxsessions = {}