You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by bu...@apache.org on 2013/02/21 08:07:40 UTC

svn commit: r851375 [2/2] - in /websites/staging/cayenne/trunk/content: ./ docs/3.1/cayenne-guide/

Modified: websites/staging/cayenne/trunk/content/docs/3.1/cayenne-guide/performance-tuning.html
==============================================================================
--- websites/staging/cayenne/trunk/content/docs/3.1/cayenne-guide/performance-tuning.html (original)
+++ websites/staging/cayenne/trunk/content/docs/3.1/cayenne-guide/performance-tuning.html Thu Feb 21 07:07:39 2013
@@ -3,8 +3,9 @@
    <title xmlns:d="http://docbook.org/ns/docbook">Chapter&nbsp;11.&nbsp;Performance Tuning</title><link rel="stylesheet" type="text/css" href="css/cayenne-doc.css"><meta xmlns:d="http://docbook.org/ns/docbook" name="keywords" content="Cayenne 3.1B3-SNAPSHOT documentation"><meta xmlns:d="http://docbook.org/ns/docbook" name="description" content="User documentation for Apache Cayenne version 3.1B3-SNAPSHOT"><link rel="home" href="index.html" title="Cayenne Guide"><link rel="up" href="cayenne-guide-part2.html" title="Part&nbsp;II.&nbsp;Cayenne Framework"><link rel="prev" href="lifecycle-events.html" title="Chapter&nbsp;10.&nbsp;Lifecycle Events"><link rel="next" href="customizing-cayenne-runtime.html" title="Chapter&nbsp;12.&nbsp;Customizing Cayenne Runtime"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div xmlns:d="http://docbook.org/ns/docbook" class="navheader"><table width="100%" summary="Navigation header"><tr><th class="versioni
 nfo">v.3.1B3-SNAPSHOT</th><th align="center">Chapter&nbsp;11.&nbsp;Performance Tuning</th><th></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="lifecycle-events.html">Prev</a>&nbsp;</td><th width="60%" align="center"><a accesskey="u" href="cayenne-guide-part2.html">Part&nbsp;II.&nbsp;Cayenne Framework</a></th><td width="20%" align="right">&nbsp;<a accesskey="n" href="customizing-cayenne-runtime.html">Next</a></td></tr></table><hr></div><div class="chapter" title="Chapter&nbsp;11.&nbsp;Performance Tuning"><div class="titlepage"><div><div><h2 class="title"><a name="performance-tuning"></a>Chapter&nbsp;11.&nbsp;Performance Tuning</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="performance-tuning.html#prefetching">Prefetching</a></span></dt><dt><span class="section"><a href="performance-tuning.html#datarows">Data Rows</a></span></dt><dt><span class="section"><a href="performance-tuning.html#iterated-que
 ries">Iterated Queries</a></span></dt><dt><span class="section"><a href="performance-tuning.html#paginated-queries">Paginated Queries</a></span></dt><dt><span class="section"><a href="performance-tuning.html#caching-and-fresh-data">Caching and Fresh Data</a></span></dt><dt><span class="section"><a href="performance-tuning.html#turning-off-synchronization-of-objectcontexts">Turning off Synchronization of ObjectContexts</a></span></dt></dl></div><div class="section" title="Prefetching"><div class="titlepage"><div><div><h2 class="title"><a name="prefetching"></a>Prefetching</h2></div></div></div><p>Prefetching is a technique that allows to bring back in one query not only the queried
             objects, but also objects related to them. In other words it is a controlled eager
             relationship resolving mechanism. Prefetching is discussed in the "Performance Tuning"
-            chapter, as it is a powerful performance optimization method. Another common application
-            of prefetching is for refreshing stale object relationships.</p><p>Prefetching example:
+            chapter, as it is a powerful performance optimization method. However another common
+            application of prefetching is to refresh stale object relationships, so more generally
+            it can be viewed as a technique for managing subsets of the object graph.</p><p>Prefetching example:
             </p><pre class="programlisting">SelectQuery query = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> SelectQuery(Artist.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>);
 
 <span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// this instructs Cayenne to prefetch one of Artist's relationships</span>
@@ -12,8 +13,8 @@ query.addPrefetch(<span xmlns="http://ww
 
 <span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// query is expecuted as usual, but the resulting Artists will have</span>
 <span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// their paintings "inflated"</span>
-List&lt;Artist&gt; artists = context.performQuery(query);</pre><p>
-            All types of relationships can be preftetched - to-one, to-many, flattened. </p><p>A prefetch can span multiple relationships:
+List&lt;Artist&gt; artists = context.performQuery(query);</pre><p>All
+            types of relationships can be preftetched - to-one, to-many, flattened. </p><p>A prefetch can span multiple relationships:
             </p><pre class="programlisting"> query.addPrefetch(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"paintings.gallery"</span>);</pre><p>A query can have multiple
             prefetches:</p><pre class="programlisting">query.addPrefetch(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"paintings"</span>);
 query.addPrefetch(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"paintings.gallery"</span>); </pre><p>If a query is fetching DataRows, all "disjoint" prefetches are ignored, only "joint"
@@ -55,11 +56,134 @@ query.addPrefetch(<span xmlns="http://ww
                 regular disjoint prefetches may produce invalid results or generate inefficient
                 fetch-the-entire table SQL when fetch limit is in effect. </p><p>The disadvantage is that query SQL can get unwieldy for large result sets, as each
                 object will have to have its own condition in the WHERE clause of the generated
-                SQL.</p></div><div class="section" title="Joint Prefetching Semantics"><div class="titlepage"><div><div><h3 class="title"><a name="joint-prefetch-semantics"></a>Joint Prefetching Semantics</h3></div></div></div><p>Joint senantics results in a single SQL statement for root objects and any number
+                SQL.</p></div><div class="section" title="Joint Prefetching Semantics"><div class="titlepage"><div><div><h3 class="title"><a name="joint-prefetch-semantics"></a>Joint Prefetching Semantics</h3></div></div></div><p>Joint semantics results in a single SQL statement for root objects and any number
                 of jointly prefetched paths. Cayenne processes in memory a cartesian product of the
                 entities involved, converting it to an object tree. It uses OUTER joins to connect
                 prefetched entities.</p><p>Joint is the most efficient prefetch type of the three as far as generated SQL
                 goes. There's always just 1 SQL query generated. Its downsides are the potentially
                 increased amount of data that needs to get across the network between the
                 application server and the database, and more data processing that needs to be done
-                on the Cayenne side.</p></div></div><div class="section" title="Data Rows"><div class="titlepage"><div><div><h2 class="title"><a name="datarows"></a>Data Rows</h2></div></div></div></div><div class="section" title="Iterated Queries"><div class="titlepage"><div><div><h2 class="title"><a name="iterated-queries"></a>Iterated Queries</h2></div></div></div></div><div class="section" title="Paginated Queries"><div class="titlepage"><div><div><h2 class="title"><a name="paginated-queries"></a>Paginated Queries</h2></div></div></div></div><div class="section" title="Caching and Fresh Data"><div class="titlepage"><div><div><h2 class="title"><a name="caching-and-fresh-data"></a>Caching and Fresh Data</h2></div></div></div><div class="section" title="Object Caching"><div class="titlepage"><div><div><h3 class="title"><a name="object-caching"></a>Object Caching</h3></div></div></div></div><div class="section" title="Query Result Caching"><div class="titlepage"><div><div><h
 3 class="title"><a name="query-result-caching"></a>Query Result Caching</h3></div></div></div></div></div><div class="section" title="Turning off Synchronization of ObjectContexts"><div class="titlepage"><div><div><h2 class="title"><a name="turning-off-synchronization-of-objectcontexts"></a>Turning off Synchronization of ObjectContexts</h2></div></div></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="lifecycle-events.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="cayenne-guide-part2.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="customizing-cayenne-runtime.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;10.&nbsp;Lifecycle Events&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;12.&nb
 sp;Customizing Cayenne Runtime</td></tr></table></div></body></html>
\ No newline at end of file
+                on the Cayenne side.</p></div></div><div class="section" title="Data Rows"><div class="titlepage"><div><div><h2 class="title"><a name="datarows"></a>Data Rows</h2></div></div></div><p>Converting result set data to Persistent objects and registering these objects in the
+            ObjectContext can be an expensive operation compareable to the time spent running the
+            query (and frequently exceeding it). Internally Cayenne builds the result as a list of
+            DataRows, that are later converted to objects. Skipping the last step and using data in
+            the form of DataRows can significantly increase performance. </p><p>DataRow is a simply a map of values keyed by their DB column name. It is a ubiqutous
+            representation of DB data used internally by Cayenne. And it can be quite usable as is
+            in the application in many cases. So performance sensitive selects should consider
+            DataRows - it saves memory and CPU cycles. All selecting queries support DataRows
+            option,
+            e.g.:</p><pre class="programlisting">SelectQuery query = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> SelectQuery(Artist.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>);
+query.setFetchingDataRows(true);
+
+List&lt;DataRow&gt; rows = context.performQuery(query); </pre><pre class="programlisting">SQLTemplate query = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> SQLTemplate(Artist.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>, <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"SELECT * FROM ARTIST"</span>);
+query.setFetchingDataRows(true);
+
+List&lt;DataRow&gt; rows = context.performQuery(query);</pre><p>Moreover DataRows may be converted to Persistent objects later as needed. So e.g. you
+            may implement some in-memory filtering, only converting a subset of fetched
+            objects:</p><pre class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// you need to cast ObjectContext to DataContext to get access to 'objectFromDataRow'</span>
+DataContext dataContext = (DataContext) context;
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">for</span>(DataRow row : rows) {
+    <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">if</span>(row.get(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"DATE_OF_BIRTH"</span>) != null) {
+        Artist artist = dataContext.objectFromDataRow(Artist.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>, row);
+        <span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// do something with Artist...</span>
+        ...
+    }
+}</pre></div><div class="section" title="Iterated Queries"><div class="titlepage"><div><div><h2 class="title"><a name="iterated-queries"></a>Iterated Queries</h2></div></div></div><p>While contemporary hardware may easily allow applications to fetch hundreds of
+            thousands or even millions of objects into memory, it doesn't mean this is always a good
+            idea to do so. You can optimize processing of very large result sets with two techniques
+            discussed in this and the following chapter - iterated and paginated queries. </p><p>Iterated query is not actually a special query. Any selecting query can be executed in
+            iterated mode by the DataContext (like in the previous example, a cast to DataContext is
+            needed). DataContext returns an object called <code class="code">ResultIterator</code> that is backed
+            by an open ResultSet. Data is read from ResultIterator one row at a time until it is
+            exhausted. Data comes as a DataRows regardless of whether the orginating query was
+            configured to fetch DataRows or not. A ResultIterator must be explicitly closed to avoid
+            JDBC resource leak.</p><p>Iterated query provides constant memory performance for arbitrarily large ResultSets.
+            This is true at least on the Cayenne end, as JDBC driver may still decide to bring the
+            entire ResultSet into the JVM memory. </p><p>Here is a full
+            example:</p><pre class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// you need to cast ObjectContext to DataContext to get access to 'performIteratedQuery'</span>
+DataContext dataContext = (DataContext) context;
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// create a regular query</span>
+SelectQuery q = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> SelectQuery(Artist.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>);
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// ResultIterator operations all throw checked CayenneException</span>
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// moreover 'finally' is required to close it</span>
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">try</span> {
+
+    ResultIterator it = dataContext.performIteratedQuery(q);
+
+    <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">try</span> {
+        <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">while</span>(it.hasNextRow()) {
+            <span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// normally we'd read a row, process its data, and throw it away</span>
+            <span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// this gives us constant memory performance</span>
+            Map row = (Map) it.nextRow();
+            
+            <span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// do something with the row...</span>
+            ...
+        }
+    }
+    <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">finally</span> {
+        it.close();
+    }
+}
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">catch</span>(CayenneException e) {
+   e.printStackTrace();
+}
+</pre><p>Also
+            common sense tells us that ResultIterators should be processed and closed as soon as
+            possible to release the DB connection. E.g. storing open iterators between HTTP requests
+            and for unpredictable length of time would quickly exhaust the connection pool.</p></div><div class="section" title="Paginated Queries"><div class="titlepage"><div><div><h2 class="title"><a name="paginated-queries"></a>Paginated Queries</h2></div></div></div><p>Enabling query pagination allows to load very large result sets in a Java app with
+            very little memory overhead (much smaller than even the DataRows option discussed
+            above). Moreover it is completely transparent to the application - a user gets what
+            appears to be a list of Persistent objects - there's no iterator to close or DataRows to
+            convert to objects:</p><p>
+            </p><pre class="programlisting">SelectQuery query = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> SelectQuery(Artist.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>);
+query.setPageSize(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">50</span>);
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">// the fact that result is paginated is transparent</span>
+List&lt;Artist&gt; artists = ctxt.performQuery(query);</pre><p>
+        </p><p>Having said that, DataRows option can be combined with pagination, providing the best
+            of both
+            worlds:</p><pre class="programlisting">SelectQuery query = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> SelectQuery(Artist.<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span>);
+query.setPageSize(<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">50</span>);
+query.setFetchingDataRows(true);
+
+List&lt;DataRow&gt; rows = ctxt.performQuery(query);</pre><p>The way pagination works internally, it first fetches a list of IDs for the root
+            entity of the query. This is very fast and initially takes very little memory. Then when
+            an object is requested at an arbitrary index in the list, this object and adjacent
+            objects (a "page" of objects that is determined by the query pageSize parameter) are
+            fetched together by ID. Subsequent requests to the objects of this "page" are served
+            from memory.</p><p>An obvious limitation of pagination is that if you eventually access all objects in
+            the list, the memory use will end up being the same as with no pagination. However it is
+            still a very useful approach. With some lists (e.g. multi-page search results) only a
+            few top objects are normally accessed. At the same time pagination allows to estimate
+            the full list size without fetching all the objects. And again - it is completely
+            transparent and looks like a normal query.</p></div><div class="section" title="Caching and Fresh Data"><div class="titlepage"><div><div><h2 class="title"><a name="caching-and-fresh-data"></a>Caching and Fresh Data</h2></div></div></div><div class="section" title="Object Caching"><div class="titlepage"><div><div><h3 class="title"><a name="object-caching"></a>Object Caching</h3></div></div></div></div><div class="section" title="Query Result Caching"><div class="titlepage"><div><div><h3 class="title"><a name="query-result-caching"></a>Query Result Caching</h3></div></div></div></div></div><div class="section" title="Turning off Synchronization of ObjectContexts"><div class="titlepage"><div><div><h2 class="title"><a name="turning-off-synchronization-of-objectcontexts"></a>Turning off Synchronization of ObjectContexts</h2></div></div></div><p>By default when a single ObjectContext commits its changes, all other contexts in the
+            same runtime receive an event that contains all the committed changes. This allows them
+            to update their cached object state to match the latest committed data. There are
+            however many problems with this ostensibly helpful feature. In short - it works well in
+            environments with few contexts and in unclustered scenarios, such as single user desktop
+            applications, or simple webapps with only a few users. More specifically:</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"><p>The performance of synchronization is (probably worse than) O(N) where N
+                        is the number of peer ObjectContexts in the system. In a typical webapp N
+                        can be quite large. Besides for any given context, due to locking on
+                        synchronization, context own performance will depend not only on the queries
+                        that it runs, but also on external events that it does not control. This is
+                        unacceptable in most situations. </p></li><li class="listitem"><p>Commit events are untargeted - even contexts that do not hold a given
+                        updated object will receive the full event that they will have to
+                        process.</p></li><li class="listitem"><p>Clustering between JVMs doesn't scale - apps with large volumes of commits
+                        will quickly saturate the network with events, while most of those will be
+                        thrown away on the receiving end as mentioned above.</p></li><li class="listitem"><p>Some contexts may not want to be refreshed. A refresh in the middle of an
+                        operation may lead to unpredictable results. </p></li><li class="listitem"><p>Synchronization will interfere with optimistic locking. </p></li></ul></div><p>So we've made a good case for disabling synchronization in most webapps.
+            To do that, set to "false" the following DI property -
+                <code class="code">Constants.SERVER_CONTEXTS_SYNC_PROPERTY</code>, using one of the standard
+            Cayenne DI approaches. E.g. from command
+            line:</p><pre class="programlisting">java -Dcayenne.server.contexts_sync_strategy=false</pre><p>Or
+            by changing the standard properties Map in a custom extensions
+            module:</p><pre class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">class</span> MyModule <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">implements</span> Module {
+
+    <span xmlns="http://www.w3.org/1999/xhtml" class="hl-annotation">@Override</span>
+    <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">public</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">void</span> configure(Binder binder) {
+        binder.bindMap(Constants.PROPERTIES_MAP).put(Constants.SERVER_CONTEXTS_SYNC_PROPERTY, <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"false"</span>);
+    }
+}</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="lifecycle-events.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="cayenne-guide-part2.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="customizing-cayenne-runtime.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;10.&nbsp;Lifecycle Events&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;12.&nbsp;Customizing Cayenne Runtime</td></tr></table></div></body></html>
\ No newline at end of file

Modified: websites/staging/cayenne/trunk/content/docs/3.1/cayenne-guide/server-configuration-properties.html
==============================================================================
--- websites/staging/cayenne/trunk/content/docs/3.1/cayenne-guide/server-configuration-properties.html (original)
+++ websites/staging/cayenne/trunk/content/docs/3.1/cayenne-guide/server-configuration-properties.html Thu Feb 21 07:07:39 2013
@@ -2,7 +2,7 @@
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title xmlns:d="http://docbook.org/ns/docbook">Appendix&nbsp;A.&nbsp;Configuration Properties</title><link rel="stylesheet" type="text/css" href="css/cayenne-doc.css"><meta xmlns:d="http://docbook.org/ns/docbook" name="keywords" content="Cayenne 3.1B3-SNAPSHOT documentation"><meta xmlns:d="http://docbook.org/ns/docbook" name="description" content="User documentation for Apache Cayenne version 3.1B3-SNAPSHOT"><link rel="home" href="index.html" title="Cayenne Guide"><link rel="up" href="index.html" title="Cayenne Guide"><link rel="prev" href="current-limitations.html" title="Chapter&nbsp;18.&nbsp;Current Limitations"><link rel="next" href="client-configuration-properties.html" title="Appendix&nbsp;B.&nbsp;Service Collections"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div xmlns:d="http://docbook.org/ns/docbook" class="navheader"><table width="100%" summary="Navigation header"><tr><th class="versioninfo">v.3.1B3-SNAPSHOT</th><th
  align="center">Appendix&nbsp;A.&nbsp;Configuration Properties</th><th></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="current-limitations.html">Prev</a>&nbsp;</td><th width="60%" align="center">&nbsp;</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="client-configuration-properties.html">Next</a></td></tr></table><hr></div><div class="appendix" title="Appendix&nbsp;A.&nbsp;Configuration Properties"><div class="titlepage"><div><div><h2 class="title"><a name="server-configuration-properties"></a>Appendix&nbsp;A.&nbsp;Configuration Properties</h2></div></div></div><p>Note that the property names below are defined as constants in
             <code class="code">org.apache.cayenne.configuration.Constants</code> interface. </p><p>
-        </p><table frame="void" id="d0e2253"><caption>Table&nbsp;A.1.&nbsp;Configuration Properties Recognized by ServerRuntime and/or ClientRuntime</caption><col width="67%"><col width="15%"><col width="18%"><thead><tr>
+        </p><table frame="void" id="d0e2534"><caption>Table&nbsp;A.1.&nbsp;Configuration Properties Recognized by ServerRuntime and/or ClientRuntime</caption><col width="67%"><col width="15%"><col width="18%"><thead><tr>
                     <th>Property</th>
                     <th>Possible Values</th>
                     <th>Default Value</th>