You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2008/02/21 14:46:07 UTC

svn commit: r629780 - in /myfaces/orchestra/trunk/core/src/site: site.xml xdoc/implementation.xml xdoc/introduction.xml

Author: skitching
Date: Thu Feb 21 05:46:06 2008
New Revision: 629780

URL: http://svn.apache.org/viewvc?rev=629780&view=rev
Log:
Add implementation section.

Added:
    myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml   (with props)
Modified:
    myfaces/orchestra/trunk/core/src/site/site.xml
    myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml

Modified: myfaces/orchestra/trunk/core/src/site/site.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/site.xml?rev=629780&r1=629779&r2=629780&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/site.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/site.xml Thu Feb 21 05:46:06 2008
@@ -40,7 +40,7 @@
             <item name="Introduction" href="introduction.html"/>
             <item name="Conversations" href="conversation.html"/>
             <item name="Persistence" href="persistence.html"/>
-            <item name="Glossary" href="glossary.html"/>
+            <item name="Implementation" href="implementation.html"/>
             <item name="Installation" href="installation.html"/>
             <item name="Conversation API Usage" href="usage.html"/>
             <item name="ViewController" href="viewController.html"/>
@@ -48,6 +48,7 @@
             <item name="JSF Component Bindings" href="component-bindings.html"/>
             <item name="TODO" href="todo.html"/>
             <item name="FAQs" href="faqs.html"/>
+            <item name="Glossary" href="glossary.html"/>
         </menu>
 
         <menu ref="reports"/>

Added: myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml?rev=629780&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml (added)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml Thu Feb 21 05:46:06 2008
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE document PUBLIC "-//Apache Software Foundation//DTD XDOC 1.0//EN"
+	"http://www.apache.org/dtd/xdoc.dtd">
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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>Apache MyFaces Orchestra - Implementation Details</title>
+	</properties>
+
+	<body>
+		<section name="Overview">
+			<p>
+			To understand what features Orchestra can provide, and what its limitations are,
+			it can be helpful to understand how it works. This is entirely optional, and
+			you can skip this section if you wish.
+			</p>
+			<p>
+			Please note that the information in this section describes how the current
+			implementation works. This is subject to change in future releases.
+			</p>
+		</section>
+		<section name="Proxies">
+			<p>
+			Orchestra uses object "proxies" that intercept calls to real beans in order to
+			track data flows and to redirect them as appropriate.
+			</p>
+			<p>
+			When a bean is configured to live in an Orchestra scope, any time an instance
+			of that bean is created then what is returned is not a reference to the actual
+			type, but instead a proxy object. The proxy object is of the same type (ie
+			"x instanceof TheExpectedType" will return true). If you use getClass() on the
+			proxy object, it may show that the proxy is a subclass of the expected type
+			(depending on how the proxying is implemented). However in most cases this doesn't
+			matter; the proxy can be treated exactly as if it was of the expected type, and of
+			course provides all the same methods that the expected type supports. 
+			</p>
+			<p>
+			Of course this relies upon instances being created in a way that Orchestra can
+			intercept in order to create the proxy object. The most common usage is expected
+			to be JSF with Spring; in this setup a custom JSF VariableResolver is automatically
+			registered so that EL expressions such as "#{myBean}" cause Spring to handle the
+			lookup, and Orchestra's Spring scope-handler will then automatically proxy the bean.
+			However other presentation-tier approaches (eg plain jsp or servlets) and other
+			bean-management implementations (such as Google Guice) should be usable with
+			Orchestra as long as there is a mechanism for the appropriate proxies to be
+			created when needed.
+			</p>
+			<p>
+			The proxy has two distinct functions: to direct calls to an appropriate "real"
+			underlying bean (similar to Spring's aop:scoped-proxy), and to run an arbitrary
+			set of "advices" around each method call on the proxy. In particular, an advice is
+			used to implement Orchestra's persistence support (see later).
+			</p>
+		</section>
+		<section name="Indirection">
+			<p>
+			The proxy object returned by orchestra during a bean lookup does not directly hold
+			a reference to the underlying bean. Instead it just keeps:
+			<ul>
+			<li>a reference to a Scope object</li>
+			<li>a conversation-name string</li>
+			<li>a bean-name string</li>
+			</ul>
+			</p>
+			<p>
+			Invoking any method on the proxy object causes it to:
+			<ul>
+			<li>fetch the ConversationManager object for the current user</li>
+			<li>fetch the current ConversationContext for the user's current window</li>
+			<li>fetch the correct Conversation instance (using the conversation-name)</li>
+			<li>
+			fetch the correct target object from the Conversation (using bean-name),
+			or (if the instance does not yet exist) create an instance and store it in the
+			conversation.
+			</li> 
+			</ul>
+			Then the originally invoked method is forwarded to the target object that was found.
+			</p>
+			<p>
+			Any call on a method of the proxy will therefore be forwarded to an instance that is
+			stored in a specific Conversation object. If the Conversation object is deleted, then
+			invoking a method on the proxy will just create a new Conversation instance and a
+			new instance of the target bean. Because of this, proxy objects can be retained
+			for any length of time; they never point to "stale" objects. This in turn allows
+			Orchestra to discard conversation objects at appropriate times without breaking
+			code holding references to those objects.
+			</p>
+			<p>
+			There is of course a performance penalty for this; invoking a method on a
+			conversation-scoped object (via its proxy) require a couple of hashmap lookups to
+			locate the target object, plus whatever internal overhead the proxying library
+			(currently CGLIB) adds.
+			</p>
+			<p>
+			Note that in Orchestra Core 1.0 a spring aop:scoped-proxy tag was needed on bean 
+			definitions in order to enable the above functionality. Orchestra does function
+			without the indirection feature, but code must then be careful not to store any such
+			references for later use; instead beans can only be referenced via EL expressions.
+			It was strongly recommended in Orchestra 1.0 that aop:scoped-proxy be added to
+			each conversation-scoped bean definition and it is now automatic in Orchestra
+			Core 1.1.
+			</p>
+		</section>
+		<section name="Storing Conversations">
+			<p>
+			Conversations are stored within a ConversationContext which is stored within a 
+			ConversationManager which is in turn stored within an HttpSession.
+			</p>
+			<p>
+			A conversation and its associated data therefore lasts as long as the user's
+			session object, unless explicitly deleted by Orchestra.
+			</p>
+		</section>
+		<section name="Access Scope">
+			<p>
+			When a proxy is invoked, and retrieves a target bean from a specific conversation
+			it also marks the conversation as "accessed". This allows Orchestra to determine
+			whether a conversation is currently "in use", or whether the user has navigated off
+			to some other part of the webapp. When the conversation is marked as "access" scope,
+			and is not in use then it is simple to detect this and discard the conversation
+			(together with all the bean instances that are stored in it).
+			</p>
+			<p>
+			Because proxies simply trigger the creation of new instances (and a conversation to
+			hold it) when needed, a user returning to an "access scope" page simply causes a
+			"fresh" version of the page state to be created. 
+			</p>
+			<p>
+			This approach is quite different from some other libraries that provide conversation
+			scope. In particular, it does not require any elaborate flow-control state charts
+			to control navigation. With Orchestra the detection of beans that are no longer in
+			use is completely automatic. 
+			</p>
+		</section>
+		<section name="Manual Scope">
+			<p>
+			With manual scope, Conversation instances are only deleted when application code
+			makes an explicit call to the Orchestra API, or when a JSF tag in a page makes
+			that call. The application therefore itself determines when a set of beans
+			(ie a conversation) is no longer needed. The implementation of this is obvious:
+			a ConversationContext object holds a map of conversations by name, and this
+			just removes the appropriate (name, Conversation) entry from that map. All the
+			beans in the conversation then become elegible for garbage-collection. Note
+			that Orchestra provides an option for beans in a conversation to be notified
+			when the conversation is terminated, which provides a kind of "destructor"
+			opportunity.
+			</p>
+		</section>
+		<section name="Multiple beans in a single Scope">
+			<p>
+			Each conversation has a name. By default, a conversation-scoped bean will be
+			placed in a conversation whose name is the bean-name used to retrieve that bean
+			from the dependency-injection system (Spring or other). Therefore by default
+			each conversation has only one bean in it. 
+			</p>
+			<p>
+			Configuring a group of beans to belong to the same conversation is quite
+			useful with both Access and Manual scopes. To do this, simply ensure that the
+			configuration on the bean declaration specifies a conversation name. The
+			Conversation object has a Map of the objects in it, and so therefore can
+			hold any number of different beans, keyed by their bean-name.
+			</p>
+		</section>
+		<section name="Multiple Window Support">
+			<p>
+			An http session is typically maintained via a "cookie" that identifies the session
+			to be used for each request. A web-browser can open multiple windows or tabs which
+			share the same cookies; in this situation requests from different windows will all
+			use the same http-session on the server, and therefore access exactly the same
+			instances of session-scoped objects. 
+			</p>
+			<p>
+			Unfortunately reusing session-scoped objects for completely unrelated requests
+			coming from different windows or tabs of a user's browser can cause nasty problems.
+			</p>
+			<p>
+			The Java Servlet standard does not support more than one session per user. However
+			Orchestra effectively provides this by keeping conversation objects as children of
+			a ConversationContext object. All that is needed is for each window to specify a
+			different ConversationContext object to use. Further documentation on this feature
+			can be found elsewhere on the Orchestra site.  
+			</p>
+		</section>
+		<section name="Persistence">
+			<p>
+			Each conversation can optionally have a PersistenceContext associated with it. When
+			this is configured, then after a proxy has been invoked and has determined which
+			conversation the target bean is in, it configures the PersistenceContext associated
+			with that conversation as "the global persistence context". Any persistence operations
+			performed by the target bean (or the ordinary instances it calls) therefore run in
+			the context of the persistence context for that conversation. When the method on the
+			target bean returns, the proxy restores the previous persistence context. 
+			</p>
+			<p>
+			Conversation instances are stored (indirectly) in the user session, so the persistence
+			context objects last across multiple requests, and are only discarded when the associated
+			conversation object is discarded. This allows "long running" persistence operations.
+			</p>
+			<p>
+			As noted elsewhere, this is useful only in applications where the database access and
+			the web presentation logic exist in the same physical tier. This is common for
+			small to medium applications, but the largest and most security-sensitive applications
+			typically keep database access logic in a separate tier and therefore this Orchestra
+			feature cannot be applied. However there are many single-tier applications where this
+			functionality can save a lot of developer time and effort.
+			</p>
+		</section>
+	</body>
+</document>

Propchange: myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml?rev=629780&r1=629779&r2=629780&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml Thu Feb 21 05:46:06 2008
@@ -39,8 +39,18 @@
 			<p>Orchestra Core requires only Java 1.4 and JSF 1.1.</p>
 		</section>
 		<section name="Important Information">
-			<p>At the current time, Orchestra is not safe for use with distributed sessions.
-			If you need this feature, please contact the development list.</p>
+			<p>
+			At the current time, Orchestra is not safe for use with distributed sessions.
+			If you need this feature, please contact the development list.
+			</p>
+			<p>
+			Orchestra persistence features presume the presentation tier has access to the database,
+			ie that the presentation and database-access tiers are combined. This is often the case
+			in small-to-medium web applications. Large or security-sensitive applications which separate
+			database access out into an isolated tier (eg use a "full EJB stack") cannot use the Orchestra
+			persistence facilities, although they can still make use of the regular conversational support
+			for beans in the presentation layer.
+			</p>
 		</section>
 	</body>
 </document>