Architecture
Submission types
- implement Submission [should be a better name]
- derive from BaseSubmission
- control the way to establish a connection
- RegularSubmission:
- uses protocol, typically HTTP or HTTPS, but also can use oxf: or file:
- via the Connection class
- Connection returns a SubmissionResult
- RequestDispatcherSubmission:
- uses a Servet RequestDispatcher
- ClientGetAll:
- just tells the client to do a get of a client URL
- CacheableSubmission:
- wraps around RegularSubmission to provide aggressive caching
- LocalPortletSubmission:
- local Orbeon submission within a portlet
- FilterPortletSubmission:
- only for separate deployment in portlets with replace="all"
- EchoSubmission:
Replacers
- implement Replacer
- derive from BaseReplacer
- determine what to do with the result of a connection
- AllReplacer:
- InstanceReplacer:
- TextReplacer:
- NoneReplacer:
- for replace="none"
- also used by other replace="..." if there is no response body
- also used internally RequestDispatcherSubmission to tell that no action must be taken by replacer
- RedirectReplacer:
- when 301/302 is received with replace="all"
Synchronous vs. asynchronous
Synchronous:
- Callable<SubmissionResult> runs right away
- starts connection
- handles deserialization (without replacing)
- returns SubmissionResult to caller
- so Submission.connect() returns SubmissionResult
- so XFMS.handleSubmissionResult runs right away
Async:
- Callable<SubmissionResult> added to AsynchronousSubmissionManager
- starts connection
- handles deserialization (without replacing)
- returns null to caller
- so Submission.connect() returns null
- so XFMS.handleSubmissionResult doesn't run
- XFMS.doSubmitReplace calls XFMS.handleSubmissionResult when connection is done
Replace="all" vs. others
Replace="all" is different:
- when response has content, tries to stream result to OutputStream in response
- may run in two passes
The following is to note as of 2007-08-28:
- Submission is in two phases when using anything but method="get". The two-phase mechanism has been in place since a very long time.
- Some recent changes and fixes:
- For the second phase, we now do NOT modify the containing document (if we do it's a bug) so we can keep the same dynamic state. This means we do not dispatch xforms-submit-serialize, xforms-submit-done or xforms-submit-error during the second phase.
- XFormsServer makes sure to return the containing document to the pool when document caching is enabled.
- If an error occurs during the second phase, an exception is thrown.
- If an error occurs during the first phase, then however xforms-submit-error is dispatched as usual.
Cacheable submissions
TODO Future enhancements/refactoringIssues as of 2011-08-11: - current architecture is not as clean as it should be
- lifecycle of submission, error handling, invariants are not easy to check
- extensibility is hard
- there is code duplication (in Submission types)
- etc.
Things that should be easier / done better : - combining Submission type/Replacer
- creating new Submission types
- determining what Submission type to use
- checking that error handling (and event dispatch) is correctly implemented
- CacheableSubmission should be orthogonal to other Submission types
- etc.
Notes on asynchronous submissions
During page initialization, the server may send polling events to dispatch after a delay, following this format:
var orbeonInitData = {
"server-events":[
{
"delay":9807,
"discardable":true,
"show-progress":false,
"event":"X2ztnLbujs+..."
}
]
};
The content is the same as a server event sent back through Ajax.
Background submissions
Fire-and-forget submissions
NOTE: This is obsolete as of February 2010 builds.
- In this case, Orbeon Forms does not create a new thread, but it uses the current Ajax request thread (for simplicity/economy reasons)
- when async submission is found (@mode="asynchronous"), store information but do not run submission
- XFormsServer sends Ajax response and closes connection
- THEN process queued async submissions
- Callable instances are added to XFCD when asynchronous submissions are encountered
- openConnection() was refactored to separate headers processing and remove dependency on ExternalContext
- XFCD.processAsynchronousSubmissions() is run:
- at the end of XFormsServer processing
- at the end of XFormsToXHTML processing
- converters were refactored so that endDocument() causes the the Servlet OutputStream to be closed
- allows client to entirely receive Ajax response before async submissions are processed on the server
- this works in xforms-server.xpl, where oxf:xml-converter/oxf:html-converter are placed before oxf:http-serializer
- this may not work properly for XFormsToXHTML given the complexity of the epilogue
- -> async submissions during page initialization may delay the page loading
|
|