blob: 6981cadb70463ae7264ee3e1fc06de7f334b1107 [file] [log] [blame]
<?xml version="1.0"?>
<!--
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<document>
<properties>
<title>Application Service Proposal</title>
</properties>
<body>
<section name="Browser window bound application context">
<p><b>The problem: multiple windows</b></p>
<p>
Suppose that you write an application that will have the ability to open
multiple windows at once. These windows will contain views for different
application modules. Sometimes, different windows will show the same module,
but the data or it's presentation form will be different. It is obvious that
each of the windows has an amount of state information associated with it. The
HTTP protocol is by design stateless. Because statefullness is necessary for a
multitude of applications, cookies mechanism was introduced. Usually, the
cookies passed between the server and browser carry only an identifier of the
session. The actual data is kept in the servers memory (or other storage device)
Unfortunately cookies are not appropriate for managing state information
associated with a single window. The primary way of overcoming this limitation
is encoding information about the subset of data to be displayed and the
presentation details (like sorting order) into the request URLs. This technique
allows the user to maintain multiple simultaneous sessions with the same screen
of the application in different browser windows, viewing different data sets or
using different presentation settings. This technique might be unacceptable in
two situations:
</p>
<ul>
<li>the presentation settings should not be visible in the URL so that the user
can not tamper with them. </li>
<li> the amount of state information is large and/or the generated page contains
large number of links. This would lead to generating large amounts of markup,
decreasing application responsiveness and consuming resources.</li>
</ul>
<p><b>The solution: server side window context</b></p>
<p>
A technique similar to that applied to global session data. Window specific
information can be stored on the server, and an token allowing to uniquely
identify this information can be added to all URLs generated on the page.
This way on the next request originating from a given browser window, the
application has access to the state information associated with this window.
</p>
<p><b>The problem: "Open in new window"</b></p>
<p>
If opening of windows in a multi-windowed application is utterly under control
of the application (the window is created using JavaScript, with context
identifier token removed from the URL, to inform the application that it needs
to create a new context) window contexts will work fine. In reality users will
often create new windows using "open in new window" command, or by dragging
URLs between windows. In each of the situations mentioned above, multiple
windows displaying the same URL (and thus, by definition the same collection
of cookies will appear. These windows are indistinguishable to the application,
but it is undesirable that these windows share the window context. That would
mean that changes to the state information performed in one window would affect
all future requests to the other windows in the group.
</p>
<p><b>The solution: session context tree</b></p>
<p>
To effectively detect opening of windows, the token identifying a session
context must be different for every request. Please recall the example of a few
windows opened "open in new window" command. All of them share the URL, and the
context identifying token contained in it. This means that they can access the
state information that was valid during the previous request. The data subset
displayed and the presentation settings used in all of the windows is the same.
But because there are multiple windows now, the session context must split. New
contexts must be created, inheriting the contents of the parent (previous)
context, an tokens identifying these newly generated context must be included
in all URLs generated on the associated pages.
</p>
<p><b>The problem: the "back" button</b></p>
<p>
While reading the previous paragraph, you may have an impression that it is
possible to perform educated guesses about context branching points and store
only as many contexts as there are windows simultaneously open. But when you
consider the situation when user uses "back" and "forward" buttons to navigate
the application, you'll find out that ALL of the contexts must be remembered
by the server. The state information associated with each request may be used
multiple times in the future. An LRU garbage collection scheme could be
performed on the context objects (only a fixed number of most recently accessed
context would be remembered) to conserve server's memory. Unfortunately, this
could easily lead to undesirable application operation. Imagine an application
with two windows open. An user performs an operation in the window A, then
switches to window B an performs so many operations in it that the context of
the window A is discarded. Then, performing an operation in the window A may
yield unexpected results because the state information was lost.
</p>
<p><b>Explicit vs Implicit cloning.</b></p>
<p>
All of the the session contexts have to be replicated per every hit to the
application. Memory consumption seems like an important factor to consider
here. I had an idea of reducing it a bit, by requiring the programmer to
explicitly copy the data from the previous context to the current context
that are important. This is makes using session contexts tedious, but
avoids cloning unused data over and over, when the user moves from one
screen to another (which will obviously need different state information).
This has the following downside - when the user uses a link to go back
to a screen that he visited earlier, the state information will be lost,
because the other screen didn't clone it (because it had no idea about them).
The presentation details will be reset to normal. On the other hand, if
the user pressed the "back" button multiple times to go back to that screen,
the presentation details would be remembered (the URLs contain valid
context identifier tokens). The conclusion is, that cloning all of the
stuff contained in the context gives a better user experience. Memory is
cheap these days, right? Oh, don't worry that those context have to stay
in memory forever. They should be bound to a global (cookie style) session
and discarded when the global session times out.
</p>
<p><b>A sketch of implementation</b></p>
<p>
<ul>
<li>
SessionContext interface similar to that of ServletSession
</li>
<li>
getGlobalContext() and getLocalContext() methods in RunData
</li>
<li>
a wrapper object containing a global context and multiple
local context keyed by id, to be stored in the HTTP session
</li>
<li>
context id tokens automatically picked up (after ParameterParser
runs) and the context extracted/cloned/created as needed using
the wrapper object from the session, and appropriate contexts
made available through RunData
</li>
<li>
context id added to the url by the DynamicURI et al
</li>
</ul>
</p>
</section>
</body>
</document>