<html>
<head>
<base href="https://wiki.asterisk.org/wiki">
<link rel="stylesheet" href="/wiki/s/2042/1/7/_/styles/combined.css?spaceKey=TOP&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/State+Replication">State Replication</a></h2>
<h4>Page <b>edited</b> by <a href="https://wiki.asterisk.org/wiki/display/~khunt">Ken Hunt</a>
</h4>
<br/>
<h4>Changes (1)</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> <br></td></tr>
<tr><td class="diff-changed-lines" >| <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">!DataStoreSequenceDiagram.PNG|border=1!</span> <span class="diff-added-words"style="background-color: #dfd;">!StateReplicatorPatternSequence.png|border=1!</span> | <br></td></tr>
<tr><td class="diff-unchanged" >| {center}{*}Figure 3. State Replicator* *Sequence Diagram{*}{center} | <br> <br></td></tr>
<tr><td class="diff-snipped" >...<br></td></tr>
</table>
</div> <h4>Full Content</h4>
<div class="notificationGreySide">
<h3><a name="StateReplication-Overview"></a>Overview</h3>
<p>State Replicators provide a mechanism for replicating the state of an Asterisk SCF component to support fail-over scenarios. State Replicators will be developed specifically for each component for which replication is required. The State Replicator is a remote process from the component for which it provides state replication. The State Replicator maintains run-time state data, not configuration data (input) or results necessarily intended to be persistent (output). While the State Replicator concept does not imply persistent storage, there is nothing to preclude a given implementation of a State Replicator from using relational, object or any persistent storage mechanism if a developer chooses to utilize such mechanisms as a way to achieve fault-tolerance for the implementation of the State Replicator itself.</p>
<h3><a name="StateReplication-DesignDetails"></a>Design Details</h3>
<p>The State Replicator process is remote from the component for which it is providing state replication. A simple interface exists to add/set data items in the set, or to remove data items from the set. As with all Asterisk SCF services, the State Replicator concept is manifest in a set of type-safe interfaces.</p>
<p>To support our goal of type-safe interfaces, we eschew the notion of a single base data type which all State Replicator implementations would be bound to. Since Slice (which is used to define the Asterisk SCF interfaces) does not currently support templated types, this implies that we will have an occurrence of a State Replicator "pattern", defined in Slice, for every component-specific State Replicator implementation.</p>
<p>The essence of the State Replicator pattern is the notion that the component pushes its state changes to the State Replicator, who is expected to, in short order, push the state changes to all registered listeners. All standby replicas of the component would be registered as listeners. Standby replicas are thus given constant updates of changes occurring in the active component, to enable expedient transition to an active state.</p>
<p>Figure 1 shows the basic structure of the State Replicator pattern. The <Type>StateReplicator, <Type>StateItem, etc. naming is intended to represent the fact that there are specializations required for a given instantiation of the pattern. Below the pattern representation is a contrived example for a service called ChannelServiceX to help clarify this point.</p>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> <span class="image-wrap" style=""><img src="/wiki/download/attachments/4816996/DataStorePatternInternalKey.png?version=3&modificationDate=1283978909000" style="border: 1px solid black" /></span> </td>
</tr>
<tr>
<td class='confluenceTd'> <div class="" align="center"><b>Figure 1. The State Replicator</b> <b>Pattern - Internally Keyed</b></div>
</td>
</tr>
</tbody></table>
</div>
<p>In Figure 1, we assume that both the State Replicator and the component consuming the data understand the internal structure of each StateItem, and therefore know which field can server as the identity of the item. A minor variation of the State Replicator pattern is shown in Figure 2, where the key is external to StateItem.</p>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> <span class="image-wrap" style=""><img src="/wiki/download/attachments/4816996/DataStorePatternExternalKey.png?version=3&modificationDate=1283978917069" style="border: 1px solid black" /></span> </td>
</tr>
<tr>
<td class='confluenceTd'> <div class="" align="center"><b>Figure 2. The State Replicator</b> <b>Pattern - Externally Keyed</b></div>
</td>
</tr>
</tbody></table>
</div>
<p>Several design choices are worthy of discussion:</p>
<ol>
        <li>Only one operation is defined to both add and update a state item. The setStateItems() operation is capable of both, and for multiple state items in a single call. This reduces the number of network calls to a single operation for many internal state changes.</li>
        <li>If you have concerns of transactional safety, you may want to define a specific StateItem subtype that exists to indicate removal of a named element. This would remove the need for calls to removeStateItems() altogether, and any internal transaction could then be updated within the State Replicator with a single operation invocation. This would alleviate the need for any external transaction monitoring.</li>
        <li>There is a set of accessors (i.e. 'get') operations, but the expected usage would be that only late-joiners use this interface to "catch up" to the current state of the active component. The intent is that state changes are pushed to registered listeners as they occur to allow very fast failover. However, there is nothing to prevent implementations from using a pull model.</li>
</ol>
<p>Figure 3. shows a dynamic view of the State Replicator pattern. In this view, the active component does not register as a listener, but is assumed to be configurable to do so if it were brought up or transitioned to a standby mode.</p>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> <span class="image-wrap" style=""><img src="/wiki/download/attachments/4816996/StateReplicatorPatternSequence.png?version=1&modificationDate=1305588148269" style="border: 1px solid black" /></span> </td>
</tr>
<tr>
<td class='confluenceTd'> <div class="" align="center"><b>Figure 3. State Replicator</b> <b>Sequence Diagram</b></div>
</td>
</tr>
</tbody></table>
</div>
<p>It has been discussed that, for C++, reusable components could be developed to support both State Replicator and Listener-side implementations of these interfaces, templatized on the Slice-defined, component-specific types. </p>
</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/State+Replication">View Online</a>
|
<a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=4816996&revisedVersion=18&originalVersion=17">View Changes</a>
|
<a href="https://wiki.asterisk.org/wiki/display/TOP/State+Replication?showComments=true&showCommentArea=true#addcomment">Add Comment</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>