146 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<html>
 | 
						|
 | 
						|
<head>
 | 
						|
<title>Changes to CIMOM Internals for Synchronous Enumeration</title>
 | 
						|
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
 | 
						|
</head>
 | 
						|
 | 
						|
<body bgcolor="#C0C0C0" text="#000080">
 | 
						|
 | 
						|
<p><big><u><big>Changes to CIMOM Internals for Synchronous Enumeration</big></u></big></p>
 | 
						|
 | 
						|
<p>Rev 1.0, raymcc, 14-Jan-99.</p>
 | 
						|
 | 
						|
<p>Rev 1.1, sanjes, 17-Jul-99 updated registry value that cache size is retrieved from and
 | 
						|
updated Reset description.</p>
 | 
						|
 | 
						|
<p>Rev 1.2, sanjes, 24-Jul-99 updated section on internal indicates to cover retries,
 | 
						|
overflow buffer, processing during next and new registry entries.</p>
 | 
						|
 | 
						|
<p>Rev 1.3, sanjes, 25-Jul-99 added WBEM_E_CLIENT_TOO_SLOW error and removed need for
 | 
						|
entries in self-registration object.</p>
 | 
						|
 | 
						|
<p>Rev 1.4, sanjes, 27-Jul-99 default overflow timeout bumped up to 60 seconds.</p>
 | 
						|
 | 
						|
<p>Rev 1.5, sanjes, 30-Jul-99 Removed WBEM_E_CLIENT_TOO_SLOW and timeouts.</p>
 | 
						|
 | 
						|
<p>Rev 1.6, sanjes, 3-Aug-99 Added note for Provider implementors (#8).</p>
 | 
						|
 | 
						|
<hr>
 | 
						|
 | 
						|
<p><strong>1.0  Introduction</strong></p>
 | 
						|
 | 
						|
<p>Due to various RAID entries and sheer stupidity of caching large amounts of data in
 | 
						|
CIMOM as the result of a query, this memo details changes to CIMOM internals to prevent
 | 
						|
such caching while maintaining the look-and-feel of full sychronous enumerations and
 | 
						|
queries.</p>
 | 
						|
 | 
						|
<p>There is no change in the API documentation or the user experience except for
 | 
						|
timing-related issues.</p>
 | 
						|
 | 
						|
<p>The affected APIs from <em>IWbemServices </em>are <em>CreateClassEnum,
 | 
						|
CreateInstanceEnum, </em>and <em>ExecQuery.  </em>No other APIs or the async versions
 | 
						|
are affected.</p>
 | 
						|
 | 
						|
<p>The functionality is specifically targeted at the internal implementation of <em>IEnumWbemClassObject.</em></p>
 | 
						|
 | 
						|
<p><span
 | 
						|
style="font-size:10.0pt;font-family:Arial;
 | 
						|
mso-fareast-font-family:"Times New Roman";mso-bidi-font-family:"Times New Roman";
 | 
						|
mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA"><span
 | 
						|
style="mso-spacerun: yes"> </p>
 | 
						|
</span></span>
 | 
						|
 | 
						|
<hr>
 | 
						|
 | 
						|
<p><strong>2.0  The Problem</strong></p>
 | 
						|
 | 
						|
<p>The problem is that synchronous enumerations specified with the default flags of 0 for <em>CreateClassEnum,
 | 
						|
CreateInstanceEnum, </em>and <em>ExecQuery </em>have undesirable behavior.  The
 | 
						|
entire result set is (a) cached in memory of CIMOM, and (b) the entire result is generated
 | 
						|
before the call unblocks, which is undesirable if the user in fact aborts the enumeration
 | 
						|
early on or in fact cancels it.</p>
 | 
						|
 | 
						|
<p>The amount of memory consumption can be tremendous.  The primary problem is that
 | 
						|
synchronous enumerations can fail completely whereas the semisync or async versions will
 | 
						|
succeed.</p>
 | 
						|
 | 
						|
<p>While there are flags to overcome this, they are unfortunately not the default and the
 | 
						|
semantics are slightly different anyway.</p>
 | 
						|
 | 
						|
<hr>
 | 
						|
 | 
						|
<p><strong>3.0   The Solution</strong></p>
 | 
						|
 | 
						|
<p>The solution is the retain the semantics but to change the internal delivery mechanism
 | 
						|
to due limited caching and to synchronize with the user's retrieval of information.</p>
 | 
						|
 | 
						|
<p>Therefore, the following behavior will be introduced</p>
 | 
						|
 | 
						|
<p>[1] The internal enumerator-sink currently blocks until the <em>last</em> object
 | 
						|
arrives into the sink, and then it sets an event. This will be changed such that it blocks
 | 
						|
until the arrival of the <em>first </em>object and then sets the event.</p>
 | 
						|
 | 
						|
<p>[2] During internal delivery fo the enumerator-sink, currently the objects are simply
 | 
						|
added to an array immediately.  If a Next function is concurrently being processed,
 | 
						|
we will add objects to the array up to the number of objects requested.  If a Next is
 | 
						|
not being processed, or we have received enough objects to satisfy the request to Next, we
 | 
						|
will continue to add objects up to a predefined Maximum Cache Size (obtained from
 | 
						|
ConfigMgr).  Once the cache size is exceeded, the Indicate will block and retry,
 | 
						|
waiting for a predefined Retry Interval (obtained from ConfigMgr).  On the next retry
 | 
						|
if the cache size is still exceeded, we will begin adding additional objects until we
 | 
						|
exceed a predefined overflow buffer size (obtained from ConfigMgr).  Once we
 | 
						|
fill the overflow buffer, the Indicate will internally block until it is either able to
 | 
						|
place an object into the enumerator or the enumerator is destroyed.  Each time
 | 
						|
Next(), Skip(), and NextAsync() are called, they will trigger an event that will cause the
 | 
						|
Indicate to try and place the object in the enumerator.  In addition, each time we
 | 
						|
perform an internal Indicate, we will check for low-memory conditions.  If these are
 | 
						|
reached, we will fail the enumeration with WBEM_E_OUT_OF_MEMORY.  The cache buffer
 | 
						|
size and overflow buffer size are all configurable in the registry as DWORD values.  
 | 
						|
The value names are: "MaxEnumCacheSize" and
 | 
						|
"MaxEnumOverflowSize".  These are all obtained from ConfigMgr, which if it
 | 
						|
does not find the values in the registry, will write them out with the default values.
 | 
						|
  The defaults are MaxEnumCacheSize=0x80000 and MaxEnumOverflowSize=0x20000.</p>
 | 
						|
 | 
						|
<p>[3] Remove the 20 meg test currently in place for the sync enumerator.</p>
 | 
						|
 | 
						|
<p>[4]  Ensure that if <em>Release </em>is called before the thing is finished,
 | 
						|
things unblock properly internally and the appropriate cancellations are issued.</p>
 | 
						|
 | 
						|
<p>[5] As the user calls <em>Next </em>or <em>NextAsync, </em>the objects are <em>removed </em>from
 | 
						|
the internal array and <em>Released.  </em>There will be no caching.  If the
 | 
						|
user calls <em>Next </em>for more objects than are available, the call will block until
 | 
						|
the requested number is available or until there are no more objects, at which point it is
 | 
						|
permissible to return fewer objects than requested.  Because of previous documented
 | 
						|
semantics and existing code, it is not permitted to return fewer objects than requested
 | 
						|
except at the <em>end </em>of an enumeration sequence.</p>
 | 
						|
 | 
						|
<p>[6] The caller may issue a <strong>Reset </strong>call.  For resettable
 | 
						|
enumerators, as objects are indicated in, we also store AddRef'd pointers to the objects
 | 
						|
in an array datamember.  If the operation completes before the number of cached
 | 
						|
objects exceeds the max cache size (obtained from the ConfigMgr), the call to Reset() will
 | 
						|
simply readd the objects from the cache array, into the array from which objects are
 | 
						|
delivered to the user.  If we exceed the cache size, we clear out the cache, and if
 | 
						|
Reset() is called, we will have to resubmit the operation.  This means that the
 | 
						|
original call type and <em>IWbemContext </em>object and the class name or query must be
 | 
						|
retained by the enumerator so that it can be <em>reissued </em>to rebuild the result set.
 | 
						|
  Since the caller is proving a security context at the time of a <em>Reset </em>call,
 | 
						|
  it is possible to propagate security into the reissue of <em>ExecQuery,
 | 
						|
CreateClassEnum, </em>or <em>CreateInstanceEnum.    </em>The implementation
 | 
						|
needs to cleanly cancel any pending deliveries to the internal enumerator-sink and reissue
 | 
						|
the request to a different sink internally so that the result sets from the previous
 | 
						|
request don't get mixed with the new one.</p>
 | 
						|
 | 
						|
<p>[7] <strong>Skip </strong>calls should block until the required number of objects have
 | 
						|
been received from the internal sink and discarded.</p>
 | 
						|
 | 
						|
<p>[8] IMPORTANT - Because the call to <strong>Indicate</strong> can now block, provider
 | 
						|
implementors must ensure that their call to <strong>Indicate</strong> is not blocked.
 | 
						|
  In other words, when they call <strong>Indicate</strong> they should ensure that
 | 
						|
their code is not blocking other clients from accessing their provider, or a deadlock
 | 
						|
condition can occur.  This needs to be documented.</p>
 | 
						|
 | 
						|
<p> </p>
 | 
						|
</body>
 | 
						|
</html>
 |