<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/2033/1/7/_/styles/combined.css?spaceKey=TOP&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://wiki.asterisk.org/wiki/display/TOP/Component+Threading+Design+for+Asynchronous+Operations">Component Threading Design for Asynchronous Operations</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://wiki.asterisk.org/wiki/display/~khunt">Ken Hunt</a>
    </h4>
        <br/>
                         <h4>Changes (4)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h3. Background <br></td></tr>
            <tr><td class="diff-changed-lines" >Asterisk SCF components can make use of Ice&#39;s [Asynchronous Message Dispatch (AMD)|http://www.zeroc.com/doc/Ice-3.4.1-IceTouch/manual/Cpps.9.8.html], a server-side technique for increasing scalability. Using AMD a server can receive a request but then suspend its processing in order to release the dispatch thread. Components may also use the client-side equivalent, [Asynchronous Method Invocation (AMI)|http://www.zeroc.com/doc/Ice-3.4.1-IceTouch/manual/Cpp.7.15.html], a way to invoke an operation on a server which never blocks the calling thread even for two-way calls. However, many (if not most) Asterisk SCF components will act as both client and server, where an incoming request will involve invoking one or more operations on other components in order to achieve a result. Even operations which return void and have no &quot;out&quot; parameters may throw <span class="diff-changed-words"><span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">E</span><span class="diff-added-chars"style="background-color: #dfd;">e</span>xceptions,</span> which need to be communicated to the initiator of the request. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >The Basic Routing Service falls into the category of components which will act as both server and client within a given <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">operation.</span> <span class="diff-added-words"style="background-color: #dfd;">servant.</span> An approach for managing the lifecycle of a server operation was implemented in the routing service, and is described on the remainder of this page. The impact of the design on the component&#39;s state replication is also discussed. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h3. Design <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The approach is to use what <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The approach implemented in the Basic Routing Service employs what the Ice documentation refers to as _asynchronous request chaining_, where an incoming AMD request is processed, and in that processing executes an AMI request on some other component. This simple concept is shown in Figure 1. A client invoke some operation (&quot;op&quot;) on the Server Component. The Server dispatches dependent operations to external Component X, but is free to process other work in the intervening time from when a reply is sent from Component X.  <br> <br>|!async_request_chaining.png|border=1!| <br>|*Figure 1. Asynchronous Request Chaining*| <br> <br>To support this concept, the Server Component is required to do quite a bit of bookkeeping. When an AMD dispatch is received, the servant must store enough information about the request to forward the processing of the operation to a separate worker thread. When it is invoked on the worker the thread, the operation will eventually create an AMI callback object to make AMI calls to Component X. When Component X provides its results, the AMI callback object is invoked. That callback object must then cause the remainder of the processing required in the operation to be executed with the appropriate state maintained across all of these thread hops.  <br> <br>The solution used in the Basic Routing Service was to implement an operation-specific state machine. Figure 2 shows the creation of this state machine at operation 1.3. As can be inferred from the diagram, the object that implements the state machine is also capable of being enqueued to a Work Queue.  <br> <br>|!async_op_state_machine.png|border=1!| <br>|*Figure 2. Server Component Details*| <br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>&lt;Draft!!!&gt;</p>

<h3><a name="ComponentThreadingDesignforAsynchronousOperations-Overview"></a>Overview</h3>
<p>This page describes an approach to supporting asynchronous operations in a component, as implemented in the Basic Routing Service. </p>

<h3><a name="ComponentThreadingDesignforAsynchronousOperations-Background"></a>Background</h3>
<p>Asterisk SCF components can make use of Ice's <a href="http://www.zeroc.com/doc/Ice-3.4.1-IceTouch/manual/Cpps.9.8.html" class="external-link" rel="nofollow">Asynchronous Message Dispatch (AMD)</a>, a server-side technique for increasing scalability. Using AMD a server can receive a request but then suspend its processing in order to release the dispatch thread. Components may also use the client-side equivalent, <a href="http://www.zeroc.com/doc/Ice-3.4.1-IceTouch/manual/Cpp.7.15.html" class="external-link" rel="nofollow">Asynchronous Method Invocation (AMI)</a>, a way to invoke an operation on a server which never blocks the calling thread even for two-way calls. However, many (if not most) Asterisk SCF components will act as both client and server, where an incoming request will involve invoking one or more operations on other components in order to achieve a result. Even operations which return void and have no "out" parameters may throw exceptions, which need to be communicated to the initiator of the request. </p>

<p>The Basic Routing Service falls into the category of components which will act as both server and client within a given servant. An approach for managing the lifecycle of a server operation was implemented in the routing service, and is described on the remainder of this page. The impact of the design on the component's state replication is also discussed. </p>

<h3><a name="ComponentThreadingDesignforAsynchronousOperations-Design"></a>Design</h3>
<p>The approach implemented in the Basic Routing Service employs what the Ice documentation refers to as <em>asynchronous request chaining</em>, where an incoming AMD request is processed, and in that processing executes an AMI request on some other component. This simple concept is shown in Figure 1. A client invoke some operation ("op") on the Server Component. The Server dispatches dependent operations to external Component X, but is free to process other work in the intervening time from when a reply is sent from Component X. </p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'><span class="image-wrap" style=""><img src="/wiki/download/attachments/10649930/async_request_chaining.png?version=1&amp;modificationDate=1293125396126" style="border: 1px solid black" /></span></td>
</tr>
<tr>
<td class='confluenceTd'><b>Figure 1. Asynchronous Request Chaining</b></td>
</tr>
</tbody></table>
</div>


<p>To support this concept, the Server Component is required to do quite a bit of bookkeeping. When an AMD dispatch is received, the servant must store enough information about the request to forward the processing of the operation to a separate worker thread. When it is invoked on the worker the thread, the operation will eventually create an AMI callback object to make AMI calls to Component X. When Component X provides its results, the AMI callback object is invoked. That callback object must then cause the remainder of the processing required in the operation to be executed with the appropriate state maintained across all of these thread hops. </p>

<p>The solution used in the Basic Routing Service was to implement an operation-specific state machine. Figure 2 shows the creation of this state machine at operation 1.3. As can be inferred from the diagram, the object that implements the state machine is also capable of being enqueued to a Work Queue. </p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'><span class="image-wrap" style=""><img src="/wiki/download/attachments/10649930/async_op_state_machine.png?version=1&amp;modificationDate=1293125402006" style="border: 1px solid black" /></span></td>
</tr>
<tr>
<td class='confluenceTd'><b>Figure 2. Server Component Details</b></td>
</tr>
</tbody></table>
</div>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://wiki.asterisk.org/wiki/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Component+Threading+Design+for+Asynchronous+Operations">View Online</a>
        |
        <a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=10649930&revisedVersion=2&originalVersion=1">View Changes</a>
                |
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Component+Threading+Design+for+Asynchronous+Operations?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>