(file) Return to MessageQueueService.html CVS log (file) (dir) Up to [Pegasus] / pegasus / doc

Diff for /pegasus/doc/MessageQueueService.html between version 1.1 and 1.3

version 1.1, 2002/02/05 23:14:54 version 1.3, 2002/03/12 22:57:40
Line 1 
Line 1 
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
   <html lang="en"><head>
   <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>XML Pointer Language (XPointer) Version 1.0</title><style type="text/css">
   
   body {
     margin: 2em 1em 2em;
     font-family: sans-serif;
     color: black;
     background: white;
     background-position: top left;
     background-attachment: fixed;
     background-repeat: no-repeat;
   }
   :link { color: #00C; background: transparent }
   :visited { color: #609; background: transparent }
   :active { color: #C00; background: transparent }
   
   th, td { /* ns 4 */
     font-family: sans-serif;
   }
   
   h1, h2, h3, h4, h5, h6 { text-align: left }
   /* background should be transparent, but WebTV has a bug */
   h1, h2, h3 { color: #005A9C; background: white }
   h1 { font: 170% sans-serif }
   h2 { font: 140% sans-serif }
   h3 { font: 120% sans-serif }
   h4 { font: bold 100% sans-serif }
   h5 { font: italic 100% sans-serif }
   h6 { font: small-caps 100% sans-serif }
   
   .hide { display: none }
   
   div.head { margin-bottom: 1em }
   div.head h1 { margin-top: 2em; clear: both }
   div.head table { margin-left: 2em; margin-top: 2em }
   div.head img { color: white; border: none } /* remove border from top image */
   
   p.copyright { font-size: small }
   p.copyright small { font-size: small }
   
   pre { margin-left: 2em }
   /*
   p {
     margin-top: 0.6em;
     margin-bottom: 0.6em;
   }
   */
   dt, dd { margin-top: 0; margin-bottom: 0 } /* opera 3.50 */
   dt { font-weight: bold }
   
   pre, code { font-family: monospace } /* navigator 4 requires this */
   
   ul.toc {
     list-style: disc;             /* Mac NS has problem with 'none' */
     list-style: none;
   }
   
   code           { font-family: monospace; }
   
   div.constraint,
   div.issue,
   div.note,
   div.notice     { margin-left: 2em; }
   
   li p           { margin-top: 0.3em;
                    margin-bottom: 0.3em; }
   
   div.exampleInner pre { margin-left: 1em;
                          margin-top: 0em; margin-bottom: 0em}
   div.exampleOuter {border: 4px double gray;
                     margin: 0em; padding: 0em}
   div.exampleInner { background-color: #d5dee3;
                      border-top-width: 4px;
                      border-top-style: double;
                      border-top-color: #d3d3d3;
                      border-bottom-width: 4px;
                      border-bottom-style: double;
                      border-bottom-color: #d3d3d3;
                      padding: 4px; margin: 0em }
   div.exampleWrapper { margin: 4px }
   div.exampleHeader { font-weight: bold;
                       margin: 4px}
   
   table { background-color: #d5dee3;
           width: 85% ;
           border-style: double;
           border-width: 4px;
           border-color: #d3d3d3;
   }
           </style>
   
 <html> <html>
   <head>   <head>
     <title>Pegasus Meta Dispatcher</title>     <title>Pegasus Meta Dispatcher</title>
   </head>   </head>
  
   <body>   <body>
   
   <p class="copyright">this is copyright text</p>
   
   <div class="constraint">this is a constraint</div>
   
   <div class="exampleInner"><code>this is an inner example</code></div>
     <h1>Pegasus Meta Dispatcher</h1>     <h1>Pegasus Meta Dispatcher</h1>
     <p>     <p>
       The Pegasus Meta Dispatcher is a set of classes that extend the       The Pegasus Meta Dispatcher is a set of classes that extend the
Line 12 
Line 109 
       asynchronous, and multithreaded. The primary classes consist of the       asynchronous, and multithreaded. The primary classes consist of the
       folowing:       folowing:
     </p>     </p>
     <table border="1" bgcolor="#cdcdc1" cellpadding="3" width="80%">          <table>
       <tr align="left"><th>Class</th><th>Derived from</th><th>Source file</th></tr>       <tr align="left"><th>Class</th><th>Derived from</th><th>Source file</th></tr>
         <tr><td>cimom</td><td>MessageQueue</td><td>Pegasus/Common/Cimom.h</td></tr>              <tr><td><div class="exampleInner">cimom</div></td><td>MessageQueue</td><td>Pegasus/Common/Cimom.h</td></tr>
         <tr><td>MessageQueueService</td><td>MessageQueue</td><td>Pegasus/Common/MessageQueueServices.h</td></tr>         <tr><td>MessageQueueService</td><td>MessageQueue</td><td>Pegasus/Common/MessageQueueServices.h</td></tr>
         <tr><td>CimomMessage</td><td>Message</td><td>Pegasus/Common/CimomMessage.h</td></tr>         <tr><td>CimomMessage</td><td>Message</td><td>Pegasus/Common/CimomMessage.h</td></tr>
         <tr><td>AsyncOpNode</td><td>n/a</td><td>Pegasus/Common/AsyncOpNode.h</td></tr>         <tr><td>AsyncOpNode</td><td>n/a</td><td>Pegasus/Common/AsyncOpNode.h</td></tr>
         <tr><td>AsyncDQueue</td><td>unlocked_dq</td><td>Pegasus/Common/DQueue.h</td></tr>         <tr><td>AsyncDQueue</td><td>unlocked_dq</td><td>Pegasus/Common/DQueue.h</td></tr>
         <tr><td>IPC classes</td><td>n/a</td><td>Pegasus/Common/IPC.h</td></tr>         <tr><td>IPC classes</td><td>n/a</td><td>Pegasus/Common/IPC.h</td></tr>
         <tr><td>Threading classes</td><td>n/a</td><td>Pegasus/Common/Thread.h</td></tr>         <tr><td>Threading classes</td><td>n/a</td><td>Pegasus/Common/Thread.h</td></tr>
   
     </table>     </table>
   
     <br>     <br>
     <br>     <br>
  
Line 103 
Line 202 
       The Meta Dispatcher therefore acts as a central message       The Meta Dispatcher therefore acts as a central message
       hub. Services communicate with each other <i>via</i> the Meta       hub. Services communicate with each other <i>via</i> the Meta
       Dispatcher.       Dispatcher.
           <div class="exampleOuter"><div class="exampleInner">
       <pre>       <pre>
       Service A--Message----1----> (block on semaphore)       Service A--Message----1----> (block on semaphore)
                                   |                                   |
Line 119 
Line 218 
  
     </pre>     </pre>
  
             </div></div>
     The numbered steps above are as follows:     The numbered steps above are as follows:
     <ol>     <ol>
       <li><b>Service A</b> creates a new <code>AsyncMessage</code> and       <li><b>Service A</b> creates a new <code>AsyncMessage</code> and
Line 247 
Line 347 
  
 <pre> <pre>
  
    Array<Uint32> services;     Array&lt;Uint32&gt;; services;
  
    while( services.size() == 0 )    while( services.size() == 0 )
    {    {
       q_client->find_services(String("test server"), 0, 0, &services);        q_client-&gt;find_services(String("test server"), 0, 0, &services);
       pegasus_yield();       pegasus_yield();
    }    }
  
    cout << "found server at " << services[0] << endl;     cout &lt;&lt; "found server at " &lt;&lt; services[0] &lt;&lt; endl;
  
  
 </pre> </pre>
Line 525 
Line 625 
 <pre> <pre>
       _completeAsyncResponse(msg, resp, ASYNC_OPSTATE_COMPLETE, 0);       _completeAsyncResponse(msg, resp, ASYNC_OPSTATE_COMPLETE, 0);
  
   
    }    }
 </pre> </pre>
  
 </ol> </ol>
         </p>         </p>
  
   <h2>Handling CIMMessage and Other Pre-existing Message Classes</h2>
             <p>
               Existing Messages, including all of the <code>CIMMessage</code>
               derivitives, are not configured to be asynchronous
               request/reply pairs. They are designed to travel through
               Pegasus as events that trigger other processing events,
               which is the end of their lifetime. This is not an optimal
               use model for asynchronous operation because the
               originator of the event does not require nor receive any
               completion notification. Further, there is not a
               one-to-one correspondence of "event messages" to replies.
             </p>
   
             <h3>AsyncLegacyOperationStart Message</h3>
             <p>
               The AsyncLegacyOperationStart message is an envelope that
               allows a <code>MessageQueueService</code>-based service to
               send, receive, and process pre-existing "legacy"
               messages.
             </p>
             <p>
               The <code>AsyncLegacyOperationStart</code> Message allows
               an asynchronous service to create, package, and send a
               "legacy" message to another service or, indirectly,
               enqueue it to a non-asynchronous message queue. The code
               example below shows how this works:
             </p>
   
   <pre>
   
      cout &lt;&lt; " sending LEGACY to test server" &lt;&lt; endl;
   
      Message *legacy = new Message(0x11100011,
                                    Message::getNextKey());
   
      AsyncLegacyOperationStart *req =
         new AsyncLegacyOperationStart(q_client-&gt;get_next_xid(),
                                       0,
                                       services[0],
                                       legacy,
                                       q_client-&gt;getQueueId());
      reply = q_client-&gt;SendWait(req);
      delete req;
      delete reply;
   
   </pre>
             <p>
              The code sample above shows a <code>Message</code> object
              being embedded inside an
               <code>AsyncLegacyOperationStart</code> message and sent
               using the <code>SendWait</code>API.
             </p>
   
             <h3>Default Handler for Legacy Messages</h3>
             <p>
               The <code>MessageQueueService</code> class has a default
               handler for legacy messages that extracts the
               <code>Message</code> out of its asynchronous "envelope"
               and dispatches it using the pre-existing synchronous
               interface, as shown below.
             </p>
   
   <pre>
   
   void MessageQueueService::handle_AsyncLegacyOperationStart(
                                                  AsyncLegacyOperationStart *req)
   {
      // remove the legacy message from the request and enqueue it to its destination
      Uint32 result = async_results::CIM_NAK;
   
      Message *legacy = req-&gt;act;
      if ( legacy != 0 )
      {
         MessageQueue* queue = MessageQueue::lookup(req-&gt;legacy_destination);
         if( queue != 0 )
         {
           // Enqueue the response:
            queue-&gt;enqueue(legacy);
            result = async_results::OK;
         }
      }
      _make_response(req, result);
   }
   
   </pre>
   
             <p>
               The default handler shown above extracts the legacy
               message and attempts to <code>enqueue</code> that message
               syncrhonously using the pre-existing interface.
             </p>
   
   <h3>Example of Custom Handler for Legacy Messages</h3>
             <p>
               By implementing the virtual
               <code>_handle_async_request</code> method,
               a service can choose to implement its own handler for
               Legacy messages, as the code below shows:
             </p>
   
   <ol>
   
   <li><b>Implement the virtual <code>_handle_async_request</code> method.</b></li>
   <pre>
   
   void MessageQueueServer::_handle_async_request(AsyncRequest *req)
   {
      if (req->getType() == 0x04100000 )
      {
         req->op->processing();
         handle_test_request(req);
      }
      else if ( req->getType() == async_messages::CIMSERVICE_STOP )
      {
         req->op->processing();
         handle_CimServiceStop(static_cast<CimServiceStop *>(req));
      }
   </pre>
   <li><b>Implement a dispatcher for <code>ASYNC_LEGACY_OP_START</code></b></li>
   <pre>
      else if ( req->getType() == async_messages::ASYNC_LEGACY_OP_START )
      {
         req->op->processing();
         handle_LegacyOpStart(static_cast<AsyncLegacyOperationStart *>(req));
      }
   
      else
         Base::_handle_async_request(req);
   }
   
   </pre>
   <li><b>Implement a dispatcher for <code>ASYNC_LEGACY_OP_START</code></b></li>
   <pre>
   
   void MessageQueueServer::handle_LegacyOpStart(AsyncLegacyOperationStart *req)
   {
   
      Message *legacy = req-&gt;act;
      cout &lt;&lt; " ### handling legacy messages " &lt;&lt; endl;
   
   
         AsyncReply *resp =
            new AsyncReply(async_messages::REPLY,
                           req-&gt;getKey(),
                           req-&gt;getRouting(),
                           0,
                           req-&gt;op,
                           async_results::OK,
                           req-&gt;resp,
                           req-&gt;block);
         _completeAsyncResponse(req, resp, ASYNC_OPSTATE_COMPLETE, 0 );
   
         if (legacy != 0 )
            cout &lt;&lt; " legacy msg type: " &lt;&lt; legacy-&gt;getType() &lt;&lt; endl;
   
   }
   
   </pre>
   
   
   </ol>
  
     <hr>     <hr>
   
   
   
   <h2>Sending Messages without Blocking (Async with Callback)</h2>
   
                 <p>
                   Whenever there is a possibility that the processing of
                   one message may generate a nested message (message
                   generated within the handler of a message) it is
                   necessary to send messages without blocking, and to
                   receive responses via callback routines. The diagram
                   below shows the (more complicated) flow of
                   non-blocking messages.
                 </p>
   <br>
                 <div class="exampleOuter"><div class="exampleInner">
         <pre>
         Service A--Message----1---->
                                  |
           . <-----------(return)-+----->-(loop)--->-+
           .                      |  Meta Dispatcher |
           .                      +----<-----<---<---+
           .                                      Message---2-->Service B
           .                                                            |
           .                                        <--Response--3------+
           .                                        |
           .                        +--<--<-----<-----+--(return)---->
           .                        | Meta Dispatcher |
         Service A <--Callback--4---+--->-(loop)-->---+
                      |       ^
                      +-------+
       </pre>
                   </div></div>
   
                 <h3>Test Program</h3>
   
                 <p>
                   There is a test program that sends and receives
                   non-blocking messages in
                   <code>$(PEGASUS_ROOT)/src/Pegasus/Common/tests/async_callback/</code>
                 </p>
   
                 <h3>SendAsync method</h3>
   
                 <p>
                   The <code>MessageQueueService</code> class sends
                   non-blocking messages using the <code>SendAsync</code>
                   method from <code>MessageQueueService.h</code>.
                 </p>
   <pre>
         Boolean <b><font color=#000000>SendAsync</font></b><font color=#990000>(</font>AsyncOpNode <font color=#990000>*</font>op<font color=#990000>,</font>
                           Uint32 destination<font color=#990000>,</font>
                           <font color=#009900>void</font> <font color=#990000>(</font><font color=#990000>*</font>callback<font color=#990000>)</font><font color=#990000>(</font>AsyncOpNode <font color=#990000>*</font><font color=#990000>,</font> MessageQueue <font color=#990000>*</font><font color=#990000>,</font> <font color=#009900>void</font> <font color=#990000>*</font><font color=#990000>)</font><font color=#990000>,</font>
                           MessageQueue <font color=#990000>*</font>callback_q<font color=#990000>,</font>
                           <font color=#009900>void</font> <font
                                                                 color=#990000>*</font>callback_ptr<font color=#990000>)</font><font color=#990000>;</font>
   </pre>
   
 <h2>Class Definitions</h2> <h2>Class Definitions</h2>
  
 <h3>cimom (Meta Dispatcher)</h3> <h3>cimom (Meta Dispatcher)</h3>
Line 1274 
Line 1592 
     <address><a href="mailto:mdday@us.ibm.com">Michael Day</a></address>     <address><a href="mailto:mdday@us.ibm.com">Michael Day</a></address>
 <!-- Created: Tue Feb  5 13:21:55 EST 2002 --> <!-- Created: Tue Feb  5 13:21:55 EST 2002 -->
 <!-- hhmts start --> <!-- hhmts start -->
 Last modified: Tue Feb  5 18:09:50 EST 2002  Last modified: Tue Mar 12 17:48:45 EST 2002
 <!-- hhmts end --> <!-- hhmts end -->
   </body>   </body>
 </html> </html>


Legend:
Removed from v.1.1  
changed lines
  Added in v.1.3

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2