blob: fb6400c66cf4aec9e6ff82b75b7a7593ef1d9528 [file] [view] [edit]
Sending unmetered one way calls back and forth produces a simple design, but
there are potential pitfalls: what if the server is much slower at processing
updates than the client sends them? For example, the client may load a drawing
consisting of many thousands of lines from some text file, and try to send them
all sequentially. How can we apply back pressure to the client to prevent the
server from being overwhelmed by this wave of updates?
By using the acknowledgement pattern and making the one way call `AddLine(...);`
into a two way `AddLine(...) -> ();`, we can provide feedback to the client.
This will allow the client to throttle its output as appropriate. In this
example, we'll simply have the client wait for the ack before sending the next
message it has waiting, though more complex designs could send messages
optimistically, and only throttle when they receive async acks less frequently
than expected.
Note: The source code for this example is located at
[//examples/fidl/new/canvas/diff_1](/examples/fidl/new/canvas/add_line_metered).
This directory includes tests exercising the implementation in all supported
languages, which may be run locally by executing the following from
the command line: `fx set core.x64 --with=//examples/fidl/new:tests && fx test
canvas_add_line_metered`.
First, we need to define our interface definitions and test harness. The FIDL,
CML, and realm interface definitions set up a scaffold that arbitrary
implementations can use:
<div>
<devsite-selector>
<!-- FIDL -->
<section>
<h3>FIDL</h3>
<pre class="prettyprint">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/fidl/canvas.test.fidl" highlight="diff_1" %}</pre>
</section>
<!-- CML -->
<section style="padding: 0px;">
<h3>CML</h3>
<devsite-selector style="margin: 0px; padding: 0px;">
<section>
<h3 id="canvas-add_line_metered-cml-client">Client</h3>
<pre class="prettyprint">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/meta/client.cml" %}</pre>
</section>
<section>
<h3 id="canvas-add_line_metered-cml-server">Server</h3>
<pre class="prettyprint">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/meta/server.cml" %}</pre>
</section>
<section>
<h3 id="canvas-add_line_metered-cml-realm">Realm</h3>
<pre class="prettyprint">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/realm/meta/realm.cml" %}</pre>
</section>
</devsite-selector>
</section>
</devsite-selector>
</div>
Client and server implementations can then be written in any supported language:
<div>
<devsite-selector>
<!-- Rust -->
<section style="padding: 0px;">
<h3>Rust</h3>
<devsite-selector style="margin: 0px; padding: 0px;">
<section>
<h3 id="canvas-add_line_metered-rust-client">Client</h3>
<pre class="prettyprint lang-rust">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/rust/client/src/main.rs" highlight="diff_1" %}</pre>
</section>
<section>
<h3 id="canvas-add_line_metered-rust-server">Server</h3>
<pre class="prettyprint lang-rust">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/rust/server/src/main.rs" highlight="diff_1" %}</pre>
</section>
</devsite-selector>
</section>
<!-- C++ (Natural) -->
<section style="padding: 0px;">
<h3>C++ (Natural)</h3>
<devsite-selector style="margin: 0px; padding: 0px;">
<section>
<h3 id="canvas-add_line_metered-cpp_natural-client">Client</h3>
<pre class="prettyprint lang-cc">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/cpp_natural/client/main.cc" highlight="diff_1" %}</pre>
</section>
<section>
<h3 id="canvas-add_line_metered-cpp_natural-server">Server</h3>
<pre class="prettyprint lang-cc">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/cpp_natural/server/main.cc" highlight="diff_1" %}</pre>
</section>
</devsite-selector>
</section>
<!-- C++ (Wire) -->
<section style="padding: 0px;">
<h3>C++ (Wire)</h3>
<devsite-selector style="margin: 0px; padding: 0px;">
<section>
<h3 id="canvas-add_line_metered-cpp_wire-client">Client</h3>
<pre class="prettyprint lang-cc">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/cpp_wire/client/main.cc" highlight="diff_1" %}</pre>
</section>
<section>
<h3 id="canvas-add_line_metered-cpp_wire-server">Server</h3>
<pre class="prettyprint lang-cc">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/cpp_wire/server/main.cc" highlight="diff_1" %}</pre>
</section>
</devsite-selector>
</section>
<!-- HLCPP -->
<section style="padding: 0px;">
<h3>HLCPP</h3>
<devsite-selector style="margin: 0px; padding: 0px;">
<section>
<h3 id="canvas-add_line_metered-hlcpp-client">Client</h3>
<pre class="prettyprint lang-cc">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/hlcpp/client/main.cc" highlight="diff_1" %}</pre>
</section>
<section>
<h3 id="canvas-add_line_metered-hlcpp-server">Server</h3>
<pre class="prettyprint lang-cc">{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/canvas/add_line_metered/hlcpp/server/main.cc" highlight="diff_1,diff_2" %}</pre>
</section>
</devsite-selector>
</section>
</devsite-selector>
</div>