<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>协程 on Hellokitty&#39;s Blog</title>
    <link>https://yangyang233333.github.io/tags/%E5%8D%8F%E7%A8%8B/</link>
    <description>Recent content in 协程 on Hellokitty&#39;s Blog</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Fri, 28 Aug 2026 14:55:00 +0800</lastBuildDate>
    <atom:link href="https://yangyang233333.github.io/tags/%E5%8D%8F%E7%A8%8B/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Mooncake 中的协程：从 coro_rpc 到同步接口桥接</title>
      <link>https://yangyang233333.github.io/posts/mooncake-coroutines/</link>
      <pubDate>Fri, 28 Aug 2026 14:55:00 +0800</pubDate>
      <guid>https://yangyang233333.github.io/posts/mooncake-coroutines/</guid>
      <description>&lt;p&gt;Mooncake 确实使用了协程，但它并不是把整个系统改造成“全异步架构”。截至本文分析的主分支提交 &lt;code&gt;3d1665a&lt;/code&gt;，协程主要出现在控制面 RPC、连接管理和阻塞任务卸载等 I/O 密集路径；对外接口仍大量保留同步调用形式。&lt;/p&gt;
&lt;p&gt;这形成了一个很实用的分层：内部用 C++20 协程组织异步流程，边界处再按需要转换成同步返回值或回调。&lt;/p&gt;
&lt;h2 id=&#34;技术栈&#34;&gt;技术栈&lt;/h2&gt;
&lt;p&gt;Mooncake 的协程代码主要建立在两层库之上：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;async_simple::coro::Lazy&amp;lt;T&amp;gt;&lt;/code&gt; 表示一个惰性异步任务；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;yalantinglibs&lt;/code&gt; 的 &lt;code&gt;coro_rpc&lt;/code&gt; 和 &lt;code&gt;coro_io&lt;/code&gt; 提供异步 RPC、网络连接与线程池调度。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;典型代码形态如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;async_simple&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;coro&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;Lazy&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;Result&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; request() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&lt;/span&gt; response &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;co_await&lt;/span&gt; client.send_request(...);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;co_return&lt;/span&gt; response;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; 创建后通常不会立刻执行。它需要被另一个协程 &lt;code&gt;co_await&lt;/code&gt;，通过 &lt;code&gt;.start(...)&lt;/code&gt; 启动，或者由 &lt;code&gt;syncAwait(...)&lt;/code&gt; 驱动至完成。&lt;/p&gt;
&lt;h2 id=&#34;路径一mooncake-store-的-master-rpc&#34;&gt;路径一：Mooncake Store 的 Master RPC&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mooncake-store/src/master_client.cpp&lt;/code&gt; 中的 &lt;code&gt;MasterClient::invoke_rpc&lt;/code&gt; 是最清晰的例子。它的外部签名是同步的：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tl&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;expected&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;ReturnType, ErrorCode&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MasterClient&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;invoke_rpc(Args&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;... args);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;函数内部却先构造 &lt;code&gt;Lazy&lt;/code&gt;，再连续等待两个异步阶段：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; async_simple&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;coro&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;syncAwait(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;]() &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; async_simple&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;coro&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;Lazy&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                tl&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;expected&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;ReturnType, ErrorCode&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&lt;/span&gt; pending &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;co_await&lt;/span&gt; pool&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;send_request(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;](coro_io&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;client_reuse_hint,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                coro_rpc&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;coro_rpc_client&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; client) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; client.send_request&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;ServiceMethod&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(...);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            });
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;pending.has_value()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;co_return&lt;/span&gt; tl&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;make_unexpected(ErrorCode&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;RPC_FAIL);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&lt;/span&gt; result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;co_await&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;move(pending.value());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;co_return&lt;/span&gt; result&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;result();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }());
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里有两次 &lt;code&gt;co_await&lt;/code&gt;：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
