<?xml version="1.0" encoding="UTF-8"?>
<chapter id="flow-execution-repository">
	<title>Flow execution repositories</title>
	<sect1 id="repository-intro">
		<title>Introduction</title>
		<para>
			A flow execution represents an executing flow <emphasis>at a point in time</emphasis>.
			At runtime there can be any number of flow executions active in parallel.  A single user
			can even have multiple executions active at the same time (for example, when a user is
			operating multiple windows or tabs within their browser).
		</para>
		<para>
			Many of these flow executions span multiple requests into the server and therefore 
			must be saved so they can be resumed on subsequent requests.  This presents technical
			challenges, as there must exist a stable mechanism for a new request to be associated
			with an existing execution in the view state that matches what the user expects.  This problem 
			is more difficult when you consider that many applications require use of browser
			navigational buttons, and use of these buttons involves updating local history without 
			notifying the server.
		</para>
		<para>
			The problem of flow execution persistence is addressed by Spring Web Flow's <emphasis>flow
			execution repository subsystem</emphasis>.  In this chapter, you will learn how to use the system
			to manage the storage of active web conversations in a stable manner.
		</para>
    </sect1>
    <sect1 id="repository-architecture-overview">
    	<title>Repository architecture overview</title>
    	<para>
    		Recall the following bullet points noting what happens when a flow execution enters a ViewState:
    	</para>
    	<para>
    		<orderedlist>
    			<listitem>
    				<para>
						When a flow execution reaches a <literal>ViewState</literal> it is said to have <emphasis>paused</emphasis>,
						where it waits in that state for user input to be provided so it can continue.  After pausing, the 
						<literal>ViewSelection</literal> returned is used to issue a response to the user
						that provides a vehicle for collecting the required user input.
					</para>
				</listitem>
				<listitem>
					<para>			
						User input is provided by <emphasis>signaling an event</emphasis> that
						<emphasis>resumes</emphasis> the flow execution in the paused view state.
						The input event communicates what user action was taken.
					</para>					
    			</listitem>
    		</orderedlist>
    	</para>
    	<para>
    		Each time an active flow execution is <emphasis>paused</emphasis>, it is saved out to a 
    		repository.  When the next request comes in for that flow execution, it is restored 
    		from the repository, <emphasis>resumed</emphasis>, and continued.  This process continues 
    		until the flow execution reaches an end state, at which time it is removed from the repository.
    	</para>
    	<para>
    		This process is demonstrated over the next two graphics:
    	</para>
		<mediaobject>
			<imageobject role="fo">
				<imagedata fileref="images/flowexecution-persistence.png" format="PNG" align="center"/>
			</imageobject>
			<imageobject role="html">
				<imagedata fileref="images/flowexecution-persistence.png" format="PNG" align="center"/>
			</imageobject>
			<caption>
				<para>Request one (1) - Paused flow execution persistence</para>
			</caption>
		</mediaobject>    	
		<mediaobject>
			<imageobject role="fo">
				<imagedata fileref="images/flowexecution-restoration.png" format="PNG" align="center"/>
			</imageobject>
			<imageobject role="html">
				<imagedata fileref="images/flowexecution-restoration.png" format="PNG" align="center"/>
			</imageobject>
			<caption>
				<para>Request two (2) - Paused flow execution restoration, removal on end</para>
			</caption>
		</mediaobject>    	
    </sect1>
    <sect1 id="repository-entry-identity">
    	<title>Flow execution identity</title>
    	<para>
			When a new flow execution is created, it marks the start of a new conversation between a browser 
   			and the server.  A new flow execution that is still active after startup
   			processing indicates the start of a conversation that will span more than one request
   			and needs to be persisted.  When this is the case, that flow execution is assigned
   			an <emphasis>persistent identifer</emphasis> by the repository.  By default, the
   			structure of this identifier consists of a two-part composite key.  This key is used
   			by clients to restore the flow execution on subsequent requests.
    	</para>
    	<sect2 id="conversationId">
    		<title>Conversation identifier</title>
	    	<para>
   		 		The first part of a flow execution's persistent identity is a 
   		 		unique <emphasis>conversation identifier</emphasis>.  This serves as an index into
   		 		the <emphasis>logical</emphasis> conversation between the browser and the server that 
   		 		has just started.
	    	</para>
	    </sect2>
	    <sect2 id="continuationId">
	    	<title>Continuation identifier</title>
			<para>
    			The second part of a flow execution's persistent identity is a <emphasis>continuation identifier</emphasis>.
    			This identifier serves as an index into a flow execution representing the state of the conversation 
    			<emphasis>at this point in time</emphasis>.
			</para>
		</sect2>
		<sect2 id="flowExecutionKey">
			<title>Flow execution key</title>
	    	<para>
    			Together the conversation id plus the continuation id make up the unique two-part
    			<emphasis>flow execution key</emphasis> that identifies a state 
    			of a conversation <emphasis>at a point in time</emphasis>.  By submitting this key 
    			in a subsequent request, a browser can restore the conversation at that point
    			and <emphasis>continue</emphasis> from there.
	    	</para>
	    	<para>
	    		So on a subsequent request, the conversation is resumed by restoring a flow execution
	    		from the repository using the two-part key.  After event processing, if the 
	    		flow execution is still active it is saved back out to the repository.
	    		At this time a new flow execution key is generated.  By default, that key
	    		retains the	same <emphasis>conversation identifier</emphasis>, as the same logical 
	    		conversation is in progress; however the <emphasis>continuation identifier</emphasis>
	    		changes to provide an index into the state of the flow execution
	    		at <emphasis>this new point in time</emphasis>.
	    	</para>
	    	<para>
				By submitting this new key in a subsequent request, a browser can
				restore the conversation at that point and <emphasis>continue</emphasis> from there.
				This process continues until a flow execution reaches an end state during event processing 
				signaling the end of the conversation.
	    	</para>
	    </sect2>
	</sect1>
    <sect1 id="conversation-ending">
    	<title>Conversation ending</title>
    	<para>
    		When a flow execution reaches an end state it terminates.  If the flow execution was associated 
    		with a logical conversation that spanned more than on request, it is removed from the 
    		repository.  More specifically, the entire conversation is <emphasis>ended</emphasis>, 
    		resulting in any flow execution continuations associated with the conversation being purged.
    	</para>
    	<para>
    		Once a conversation has ended, the conversation identifier is no longer valid
    		and can never be used again.
    	</para>
    </sect1>
	<sect1 id="repository-implementations">
		<title>Flow execution repository implementations</title>
		<para>
			The next section looks at the repository implementations that are available for use 
			with Spring Web Flow out-of-the-box.
		</para>
		<sect2 id="repository-simple">
			<title>Simple flow execution repository</title>
			<para>
				The simplest possible repository (<literal>SimpleFlowExecutionRepository</literal>).
				This repository stores <emphasis>exactly one</emphasis> flow execution instance per conversation
				in the user's session, invalidating it when its end state is reached.
				This repository implementation has been designed with minimal storage overhead in mind.
			</para>
			<note>
				<para>
					It is important to understand that use of this repository consistently prevents
					duplicate submission when using the back button.  If you attempt to go back
					and resubmit, the continuation id stored in your browser history will not
					match the current continuation id needed to access the flow execution and 
					access will be disallowed.
				</para>
			</note>
			<note>
				<para>
					This repository implementation should generally be used when you do not have to
					support browser navigational button use; for example, when you lock down the browser and
					require that all navigation events to be routed through Spring Web Flow.
				</para>
			</note>
		</sect2>
		<sect2 id="repository-continuation">
			<title>Continuation flow execution repository</title>
			<para>
				This repository (<literal>ContinuationFlowExecutionRepository</literal>) stores <emphasis>one to many</emphasis> flow
				execution instances per conversation in the user's session, where each flow execution represents a 
				paused and restorable state of the conversation at a point in time.  This repository implementation is
				considerably more flexible than the simple one, but incurs more storage overhead.
			</para>
			<note>
				<para>
	 				It is important to understand that use of this repository allows resubmission when
 					using the back button.  If you attempt to go back and resubmit while the conversation
 					is active, the continuation id stored in your browser history will match the
					continuation id of a previous flow execution in the repository.  Access to
					that flow execution representing the state of the conversation at that point in
					time will be granted.
				</para>
			</note>
			<para>
				Like the simple implementation, this repository implementation provides support for <emphasis>conversation
				invalidation after completion</emphasis> where once a logical 
				conversation completes (by one of its FlowExecutions reaching an end state),
				the entire conversation is invalidated.  This prevents the possibility of
				resubmission after completion.
			</para>
			<para>
				 This repository is more elaborate than the default repository, offering
				 more power (by enabling multiple continuations to exist per conversation),
				 but incurring more storage overhead.  This repository implementation should be
				 considered when you do have to support browser navigational button use.
				 This implementation is the default.
			</para>
		</sect2>
		<sect2 id="repository-client">
			<title>Client continuation flow execution repository</title>
			<para>
				This repository is entirely stateless and its use entails no server-side state
				(<literal>ClientContinuationFlowExecutionRepository</literal>).
			</para>
			<para>
				This is achieved by encoding a serialized flow execution directly into the
				flow execution continuation key that is sent in the response.
			</para>
			<para>				
				When asked to load a flow execution by its key on a subsequent request, this
				repository decodes and deserializes the flow execution, restoring it to
				the state it was in when it was serialized.
			</para>
			<note>
				<para>
	 		 		This repository implementation does not currently support
					<emphasis>conversation invalidation after completion</emphasis>, as 
					this capability requires tracking active conversations using some
					form of centralized storage, like a database table.
				</para>
			</note>
			<note>
				<para>
					Storing state (a flow execution continuation) on the client
					entails a certain security risk that should be evaluated. Furthermore, it
					puts practical constraints on the size of the flow execution.
				</para>
			</note>
		</sect2>
	</sect1>    
</chapter>