Files
rippled/md_ripple_rpc_README.html
2023-04-13 17:45:50 +00:00

109 lines
6.5 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.17"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>rippled: How to use RPC coroutines.</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">rippled
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.17 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
</div><!-- top -->
<div class="PageDoc"><div class="header">
<div class="headertitle">
<div class="title">How to use RPC coroutines. </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="autotoc_md281"></a>
Introduction.</h1>
<p>By default, an RPC handler runs as an uninterrupted task on the JobQueue. This is fine for commands that are fast to compute but might not be acceptable for tasks that require multiple parts or are large, like a full ledger.</p>
<p>For this purpose, the rippled RPC handler allows <em>suspension with continuation</em></p><ul>
<li>a request to suspend execution of the RPC response and to continue it after some function or job has been executed. A default continuation is supplied which simply reschedules the job on the JobQueue, or the programmer can supply their own.</li>
</ul>
<h1><a class="anchor" id="autotoc_md282"></a>
The classes.</h1>
<p>Suspension with continuation uses four <code><a class="elRef" href="http://en.cppreference.com/w/cpp/utility/functional/function.html">std::function</a></code>s in the <code><a class="el" href="namespaceripple_1_1RPC.html">ripple::RPC</a></code> namespace: </p><pre class="fragment">using Callback = std::function &lt;void ()&gt;;
using Continuation = std::function &lt;void (Callback const&amp;)&gt;;
using Suspend = std::function &lt;void (Continuation const&amp;)&gt;;
using Coroutine = std::function &lt;void (Suspend const&amp;)&gt;;
</pre><p>A <code>Callback</code> is a generic 0-argument function. A given <code>Callback</code> might or might not block. Unless otherwise advised, do not hold locks or any resource that would prevent any other task from making forward progress when you call a <code>Callback</code>.</p>
<p>A <code>Continuation</code> is a function that is given a <code>Callback</code> and promises to call it later. A <code>Continuation</code> guarantees to call the <code>Callback</code> exactly once at some point in the future, but it does not have to be immediately or even in the current thread.</p>
<p>A <code>Suspend</code> is a function belonging to a <code>Coroutine</code>. A <code>Suspend</code> runs a <code>Continuation</code>, passing it a <code>Callback</code> that continues execution of the <code>Coroutine</code>.</p>
<p>And finally, a <code>Coroutine</code> is a <code><a class="elRef" href="http://en.cppreference.com/w/cpp/utility/functional/function.html">std::function</a></code> which is given a <code>Suspend</code>. This is what the RPC handler gives to the coroutine manager, expecting to get called back with a <code>Suspend</code> and to be able to start execution.</p>
<h1><a class="anchor" id="autotoc_md283"></a>
The flow of control.</h1>
<p>Given these functions, the flow of RPC control when using coroutines is straight-forward.</p>
<ol type="1">
<li>The instance of <code>ServerHandler</code> receives an RPC request.</li>
<li>It creates a <code>Coroutine</code> and gives it to the coroutine manager.</li>
<li>The coroutine manager creates a <code>Coroutine</code>, starts it up, and then calls the <code>Coroutine</code> with a <code>Suspend</code>.</li>
<li>Now the RPC response starts to be calculated.</li>
<li>When the RPC handler wants to suspend, it calls the <code>Suspend</code> function with a <code>Continuation</code>.</li>
<li>Coroutine execution is suspended.</li>
<li>The <code>Continuation</code> is called with a <code>Callback</code> that the coroutine manager creates.</li>
<li>The <code>Continuation</code> may choose to execute immediately, defer execution on the job queue, or wait for some resource to be free.</li>
<li>When the <code>Continuation</code> is finished, it calls the <code>Callback</code> that the coroutine manager gave it, perhaps a long time ago.</li>
<li>This <code>Callback</code> continues execution on the suspended <code>Coroutine</code> from where it left off. </li>
</ol>
</div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.17
</small></address>
</body>
</html>