北市真https://amplifi.casa/@/KitaitiMakoto@blogs.kitaitimakoto.net/atom.xml2022-05-26T10:44:36.877054+00:00<![CDATA[Tomlrb v2.0.2リリース]]>https://blogs.kitaitimakoto.net/~/Apehuci/Toml%20v2.0.2リリース/2022-05-26T10:44:36.877054+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2022-05-26T10:44:36.877054+00:00<![CDATA[<p dir="auto">RubyのRaccベースのTOMLパーサー<a href="https://github.com/fbernier/tomlrb" rel="noopener noreferrer">Tomlrb</a>のv2.0.2をリリースした。</p>
<p dir="auto">TOML仕様の1.0に対応させるという偉業を<a href="https://github.com/gyfis" rel="noopener noreferrer">@gyfis</a>さんがやってくれた(<a href="https://github.com/fbernier/tomlrb/pull/44" rel="noopener noreferrer">Bring tomlrb closer to v1.0.0 TOML compliance #44</a>)。ありがとうございます。</p>
<p dir="auto">gyfisさんはTOMLライブラリーの比較記事を書いてくれた人でもある:<a href="https://gyfis.github.io/blog/markdown/2022/01/01/ruby-toml.html" rel="noopener noreferrer">Hey Ruby, how’s your TOML?</a></p>
<p dir="auto">これをきっかけにTomlrbにプルリクエストをくれたんだろうと思う。
これでパースは一段落なのでダンプ処理を書きたい気持ちがある。あとパースをもっと速くしたい気持ちも。</p>
<p dir="auto">TOML仕様、細かい所が意外とめんどくてパースの速度を落としてるんだよなあ。仕様完全準拠じゃなくて、八割のケースでうまく動いて速い、ぐらいのほうがバランスいい可能性もあるわ。ま、そもそもTOMLでパフォーマンスが問題になることなんてないだろうけど。</p>
]]><![CDATA[Rustで「n個のキューを使ってHTTPリクエスト」]]>https://blogs.kitaitimakoto.net/~/Apehuci/Rustで「n個のキューを使ってHTTPリクエスト」/2022-05-05T13:56:55.048949+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2022-05-05T13:56:55.048949+00:00<![CDATA[<p dir="auto">例えば1000ぐらいのページにアクセスしたいとして、順番にやってったら時間が掛かり過ぎるので並行にやりたい。</p>
<p dir="auto"><a href="https://docs.rs/reqwest/latest/reqwest/index.html" rel="noopener noreferrer">reqwest</a>と<a href="https://tokio.rs/" rel="noopener noreferrer">tokio</a>でちゃちゃっと書けば全てを並行にするのは簡単なんだけど、リソースを使い過ぎたのか何なのか(ちゃんと調べてない)、タイムアウトするやつとか出てきてしまった。</p>
<p dir="auto">そこで、同時にリクエストするのは50ぐらいにしておいて、空きができたら次のリクエスト……とすることにした。</p>
<p dir="auto">サイズドキューを使ってマルチスレッドでやればいいわけだ。のだけどRustでのサイズドキューライブラリー探しに苦労したのと、都合によりシングルスレッドでやりたかったのでasync/awaitを使ってて、そのやり方を調べるのにも苦労した。</p>
<h2 dir="auto">紆余曲折</h2>
<p dir="auto">そもそもRustの非同期も、ブログ記事とか見ることはあってもまともに書いたことなかったので改めて勉強することにした。</p>
<p dir="auto">まずは<a href="https://zenn.dev/magurotuna/books/tokio-tutorial-ja" rel="noopener noreferrer">Tokio チュートリアル (日本語訳)</a>を読む。訳者が書いているように、イキバタじゃなくてある程度基礎から学ぶことで見通し・自分のやるべきことが分かるようになった。最高。</p>
<p dir="auto">この本でサンプルもあったmpsc(マルチプロデューサー・マルチコンシューマー)を試してみるけどうまくいかず、そもそも課題にフィットしてないな、と実感し始めたところで他のライブラリーを探し始めた。「自分のやりたいのはサイズドキューなんだ、だから少なくともコンシューマー側は複数無いといけないんだ」と自覚してから見たのは、やはり本で触れられているwatch。でもこれは違う。</p>
<p dir="auto">あれこれ検索して見付けたのが<a href="https://qiita.com/legokichi/items/4f2c09330f90626600a6" rel="noopener noreferrer">非同期 Rust パターン</a>という記事。長いのだけど前半は明らかに求める内容じゃないからすっ飛ばして後半を読むと、</p>
<blockquote dir="auto">
<p>非同期対応した固定長 mpmc キューには <a href="https://docs.rs/flume/0.10.9/flume/fn.bounded.html" rel="noopener noreferrer">flume::bounded</a> が便利です。
固定長なので、バッファしていっぱいになったら producer 側は <code>.await</code> で consumer 側の消費を待てて、
consumer 側も mc の特権である <code>Stream + Clone</code> から <code>.await</code> した順に処理対象が降ってるので。</p>
</blockquote>
<p dir="auto">とあって、これだ! となった。</p>
<p dir="auto">が、既存のアプリケーションに見様見真似で試してみるも、どうもうまくいかない。そこで<a href="https://github.com/occlum/flume/blob/master/tests/async.rs" rel="noopener noreferrer">flumeのテストコード</a>なども見ながら、ステップバイステップで動かしていくことにした。</p>
<h2 dir="auto">プログラムが終了しない</h2>
<p dir="auto">サンプルっぽいコードを書いたらプログラムが終了しなかった。</p>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span>runtime<span class="punctuation">;</span>
<span class=""><span class="punctuation">#</span><span class="punctuation">[</span><span class="variable">tokio</span>::<span class="variable">main</span><span class="punctuation">]</span></span>
async <span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span><span class="constant numeric">3</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span><span class="constant numeric">3</span> <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>{}<span class="punctuation string">"</span></span><span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<pre><code dir="auto">0
1
2
</code></pre>
<p dir="auto">で、プログラムが終了しない。</p>
<h2 dir="auto">一つのワーカーだけが使われる</h2>
<p dir="auto">そういやリクエストは50個のキューから投げたいんだったな、今だと一つだけだわ、と思ってコンシューマーを増やした。</p>
<p dir="auto">それぞれがちゃんと使われるか見るために出力してみた(キューのことをここではworkerと書いた)。</p>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span>runtime<span class="punctuation">;</span>
<span class=""><span class="punctuation">#</span><span class="punctuation">[</span><span class="variable">tokio</span>::<span class="variable">main</span><span class="punctuation">]</span></span>
async <span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> capacity <span class="keyword operator">=</span> <span class="constant numeric">20</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span>capacity</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>capacity <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">for</span> j <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span><span class="constant numeric">3</span> <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rx <span class="keyword operator">=</span> rx.<span class="support function">clone</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>worker: {}, data: {}<span class="punctuation string">"</span></span><span class="punctuation">,</span> j<span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<pre><code dir="auto">worker: 0, data: 0
worker: 0, data: 1
worker: 0, data: 2
worker: 0, data: 3
worker: 0, data: 4
worker: 0, data: 5
worker: 0, data: 6
worker: 0, data: 7
worker: 0, data: 8
worker: 0, data: 9
worker: 0, data: 10
worker: 0, data: 11
worker: 0, data: 12
worker: 0, data: 13
worker: 0, data: 14
worker: 0, data: 15
worker: 0, data: 16
worker: 0, data: 17
worker: 0, data: 18
worker: 0, data: 19
</code></pre>
<p dir="auto">やはり終了しない。そして一つのワーカーしか使われていない。</p>
<h2 dir="auto">開始しない</h2>
<p dir="auto">プロデューサーとコンシューマーの順番がおかしいのかな?</p>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span>runtime<span class="punctuation">;</span>
<span class=""><span class="punctuation">#</span><span class="punctuation">[</span><span class="variable">tokio</span>::<span class="variable">main</span><span class="punctuation">]</span></span>
async <span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> capacity <span class="keyword operator">=</span> <span class="constant numeric">20</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span>capacity</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> j <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span><span class="constant numeric">3</span> <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rx <span class="keyword operator">=</span> rx.<span class="support function">clone</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>worker: {}, data: {}<span class="punctuation string">"</span></span><span class="punctuation">,</span> j<span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>capacity <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<p dir="auto">今度は始まらない(出力がない)。そして終わらない。</p>
<h2 dir="auto">動くようになった</h2>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span>runtime<span class="punctuation">;</span>
<span class=""><span class="punctuation">#</span><span class="punctuation">[</span><span class="variable">tokio</span>::<span class="variable">main</span><span class="punctuation">]</span></span>
async <span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> capacity <span class="keyword operator">=</span> <span class="constant numeric">20</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span>capacity</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> j <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span><span class="constant numeric">3</span> <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rx <span class="keyword operator">=</span> rx.<span class="support function">clone</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="">tokio<span class="punctuation">::</span></span>spawn<span class=""><span class="punctuation">(</span>async <span class="storage modifier">move</span> <span class=""><span class="punctuation">{</span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>worker: {}, data: {}<span class="punctuation string">"</span></span><span class="punctuation">,</span> j<span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>capacity <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<pre><code dir="auto">worker: 1, data: 0
worker: 1, data: 3
worker: 1, data: 4
worker: 1, data: 5
worker: 1, data: 6
worker: 1, data: 7
worker: 1, data: 8
worker: 1, data: 9
worker: 1, data: 10
worker: 1, data: 11
worker: 1, data: 12
worker: 0, data: 2
worker: 0, data: 14
worker: 0, data: 15
worker: 0, data: 16
worker: 0, data: 17
worker: 0, data: 18
worker: 0, data: 19
worker: 1, data: 13
worker: 2, data: 1
</code></pre>
<p dir="auto"><code>spawn()</code>する必要があった。</p>
<h2 dir="auto">ランタイムの明示実行:即時終了してしまう</h2>
<p dir="auto">都合により<code>tokio::main</code>マクロではなくて自分でランタイムを生成・実行したかったので、<a href="https://docs.rs/tokio/latest/tokio/runtime/index.html" rel="noopener noreferrer">tokioのドキュメント</a>を見ながら書き替えた。</p>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span>runtime<span class="punctuation">;</span>
<span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rt <span class="keyword operator">=</span> <span class="">runtime<span class="punctuation">::</span></span><span class="">Builder<span class="punctuation">::</span></span>new_current_thread<span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">enable_all</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">build</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
rt.<span class="support function">block_on</span><span class=""><span class="punctuation">(</span>async <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> capacity <span class="keyword operator">=</span> <span class="constant numeric">20</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span>capacity</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> j <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span><span class="constant numeric">3</span> <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rx <span class="keyword operator">=</span> rx.<span class="support function">clone</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="">tokio<span class="punctuation">::</span></span>spawn<span class=""><span class="punctuation">(</span>async <span class="storage modifier">move</span> <span class=""><span class="punctuation">{</span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>worker: {}, data: {}<span class="punctuation string">"</span></span><span class="punctuation">,</span> j<span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>capacity <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<p dir="auto">すると一切の出力がないまま、すぐに終了してしまった。</p>
<h2 dir="auto">インスタンスメソッドで <code>spawn</code></h2>
<p dir="auto">関係ないとは思うものの、 <code>spawn()</code> を <code>tokio</code> クレートではなくて生成したランタイムの物を使ってみる。</p>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span>runtime<span class="punctuation">;</span>
<span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rt <span class="keyword operator">=</span> <span class="">runtime<span class="punctuation">::</span></span><span class="">Builder<span class="punctuation">::</span></span>new_current_thread<span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">enable_all</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">build</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
rt.<span class="support function">block_on</span><span class=""><span class="punctuation">(</span>async <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> capacity <span class="keyword operator">=</span> <span class="constant numeric">20</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span>capacity</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> j <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span><span class="constant numeric">3</span> <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rx <span class="keyword operator">=</span> rx.<span class="support function">clone</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
rt.<span class="support function">spawn</span><span class=""><span class="punctuation">(</span>async <span class="storage modifier">move</span> <span class=""><span class="punctuation">{</span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>worker: {}, data: {}<span class="punctuation string">"</span></span><span class="punctuation">,</span> j<span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>capacity <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<p dir="auto">変わらない。</p>
<h2 dir="auto">マルチスレッド</h2>
<p dir="auto"><code>Builder</code> の呼ぶメソッドを変えてマルチスレッドにしてみる。</p>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span>runtime<span class="punctuation">;</span>
<span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rt <span class="keyword operator">=</span> <span class="">runtime<span class="punctuation">::</span></span><span class="">Builder<span class="punctuation">::</span></span>new_multi_thread<span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">enable_all</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">build</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
rt.<span class="support function">block_on</span><span class=""><span class="punctuation">(</span>async <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> capacity <span class="keyword operator">=</span> <span class="constant numeric">20</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span>capacity</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> j <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span><span class="constant numeric">3</span> <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rx <span class="keyword operator">=</span> rx.<span class="support function">clone</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
rt.<span class="support function">spawn</span><span class=""><span class="punctuation">(</span>async <span class="storage modifier">move</span> <span class=""><span class="punctuation">{</span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>worker: {}, data: {}<span class="punctuation string">"</span></span><span class="punctuation">,</span> j<span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>capacity <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<pre><code dir="auto">worker: 1, data: 1
worker: 2, data: 2
worker: 2, data: 4
worker: 2, data: 5
worker: 2, data: 6
worker: 1, data: 3
worker: 1, data: 7
worker: 1, data: 9
worker: 1, data: 10
worker: 1, data: 11
worker: 1, data: 12
worker: 1, data: 13
worker: 1, data: 14
worker: 1, data: 15
worker: 2, data: 8
worker: 2, data: 16
worker: 2, data: 17
worker: 0, data: 0
worker: 1, data: 18
worker: 0, data: 19
</code></pre>
<p dir="auto">動いた! シングルスレッドだとだめなのか……。</p>
<h2 dir="auto">ジョインハンドル</h2>
<p dir="auto">そういや <code>spawn()</code> したらジョインしないといけないんだったな(むしろマルチスレッドはなぜ動いていたんだ。速過ぎたのか?)。</p>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">futures<span class="punctuation">::</span></span><span class="">future<span class="punctuation">::</span></span>join_all<span class="punctuation">;</span>
<span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span>runtime<span class="punctuation">;</span>
<span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rt <span class="keyword operator">=</span> <span class="">runtime<span class="punctuation">::</span></span><span class="">Builder<span class="punctuation">::</span></span>new_current_thread<span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">enable_all</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">build</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
rt.<span class="support function">block_on</span><span class=""><span class="punctuation">(</span>async <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> capacity <span class="keyword operator">=</span> <span class="constant numeric">20</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span>capacity</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="storage type">let</span> workers <span class="keyword operator">=</span> <span class="constant numeric">3</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class="storage modifier">mut</span> handles <span class="keyword operator">=</span> <span class="support type">Vec</span><span class=""><span class="punctuation">::</span></span>with_capacity<span class=""><span class="punctuation">(</span>workers</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> j <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>workers <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rx <span class="keyword operator">=</span> rx.<span class="support function">clone</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="storage type">let</span> t <span class="keyword operator">=</span> rt.<span class="support function">spawn</span><span class=""><span class="punctuation">(</span>async <span class="storage modifier">move</span> <span class=""><span class="punctuation">{</span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>worker: {}, data: {}<span class="punctuation string">"</span></span><span class="punctuation">,</span> j<span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
handles.<span class="support function">push</span><span class=""><span class="punctuation">(</span>t</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>capacity <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="support function">join_all</span><span class=""><span class="punctuation">(</span>handles</span><span class=""><span class="punctuation">)</span></span>.await<span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<pre><code dir="auto">worker: 0, data: 0
worker: 0, data: 1
worker: 0, data: 2
worker: 0, data: 3
worker: 0, data: 4
worker: 0, data: 5
worker: 0, data: 6
worker: 0, data: 7
worker: 0, data: 8
worker: 0, data: 9
worker: 0, data: 10
worker: 0, data: 11
worker: 0, data: 12
worker: 0, data: 13
worker: 0, data: 14
worker: 0, data: 15
worker: 0, data: 16
worker: 0, data: 17
worker: 0, data: 18
worker: 0, data: 19
</code></pre>
<p dir="auto">ワーカーが変わらない。</p>
<p dir="auto">そして終わらない。</p>
<h2 dir="auto">プロデューサーを<code>drop</code></h2>
<p dir="auto">flumeのドキュメントに「 <code>Sender</code> は <code>Receiver</code> が全部<code>drop</code>したら終わる」「 <code>Receiver</code> は <code>Sender</code> が<code>drop</code>したら終わる」って書いてあったのを思い出してプロデューサーを <code>drop</code> してみる。</p>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">futures<span class="punctuation">::</span></span><span class="">future<span class="punctuation">::</span></span>join_all<span class="punctuation">;</span>
<span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span>runtime<span class="punctuation">;</span>
<span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rt <span class="keyword operator">=</span> <span class="">runtime<span class="punctuation">::</span></span><span class="">Builder<span class="punctuation">::</span></span>new_current_thread<span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">enable_all</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">build</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
rt.<span class="support function">block_on</span><span class=""><span class="punctuation">(</span>async <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> capacity <span class="keyword operator">=</span> <span class="constant numeric">20</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span>capacity</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="storage type">let</span> workers <span class="keyword operator">=</span> <span class="constant numeric">3</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class="storage modifier">mut</span> handles <span class="keyword operator">=</span> <span class="support type">Vec</span><span class=""><span class="punctuation">::</span></span>with_capacity<span class=""><span class="punctuation">(</span>workers</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> j <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>workers <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rx <span class="keyword operator">=</span> rx.<span class="support function">clone</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="storage type">let</span> t <span class="keyword operator">=</span> rt.<span class="support function">spawn</span><span class=""><span class="punctuation">(</span>async <span class="storage modifier">move</span> <span class=""><span class="punctuation">{</span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>worker: {}, data: {}<span class="punctuation string">"</span></span><span class="punctuation">,</span> j<span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
handles.<span class="support function">push</span><span class=""><span class="punctuation">(</span>t</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>capacity <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="support function">drop</span><span class=""><span class="punctuation">(</span>tx</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="support function">join_all</span><span class=""><span class="punctuation">(</span>handles</span><span class=""><span class="punctuation">)</span></span>.await<span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<pre><code dir="auto">worker: 0, data: 0
worker: 0, data: 1
worker: 0, data: 2
worker: 0, data: 3
worker: 0, data: 4
worker: 0, data: 5
worker: 0, data: 6
worker: 0, data: 7
worker: 0, data: 8
worker: 0, data: 9
worker: 0, data: 10
worker: 0, data: 11
worker: 0, data: 12
worker: 0, data: 13
worker: 0, data: 14
worker: 0, data: 15
worker: 0, data: 16
worker: 0, data: 17
worker: 0, data: 18
worker: 0, data: 19
</code></pre>
<p dir="auto">惜しい。プログラムは終了したが、ワーカーが切り替わらない。</p>
<h2 dir="auto">1秒スリープ</h2>
<p dir="auto">もしかして最初のワーカーが速過ぎて全部そいつが処理してしまっただけなのかも? と思ってスリープを入れてみる。</p>
<pre><code dir="auto"><span class="source"><span class="keyword">use</span> <span class="">futures<span class="punctuation">::</span></span><span class="">future<span class="punctuation">::</span></span>join_all<span class="punctuation">;</span>
<span class="keyword">use</span> <span class="">tokio<span class="punctuation">::</span></span><span class=""><span class="punctuation">{</span>runtime<span class="punctuation">,</span> <span class="">time<span class="punctuation">::</span></span><span class=""><span class="punctuation">{</span>sleep<span class="punctuation">,</span> Duration</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">}</span></span><span class="punctuation">;</span>
<span class="function"><span class="function"><span class="storage type function">fn</span> </span><span class="entity name function">main</span></span><span class="function"><span class="function"><span class="punctuation">(</span></span><span class="function"><span class="function"><span class="punctuation">)</span></span></span></span><span class="function"> </span><span class="function"><span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rt <span class="keyword operator">=</span> <span class="">runtime<span class="punctuation">::</span></span><span class="">Builder<span class="punctuation">::</span></span>new_current_thread<span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">enable_all</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">build</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>
.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
rt.<span class="support function">block_on</span><span class=""><span class="punctuation">(</span>async <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> capacity <span class="keyword operator">=</span> <span class="constant numeric">20</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class=""><span class="punctuation">(</span>tx<span class="punctuation">,</span> rx</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> <span class="">flume<span class="punctuation">::</span></span>bounded<span class=""><span class="punctuation">(</span>capacity</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="storage type">let</span> workers <span class="keyword operator">=</span> <span class="constant numeric">3</span><span class="punctuation">;</span>
<span class="storage type">let</span> <span class="storage modifier">mut</span> handles <span class="keyword operator">=</span> <span class="support type">Vec</span><span class=""><span class="punctuation">::</span></span>with_capacity<span class=""><span class="punctuation">(</span>workers</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="keyword control">for</span> j <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>workers <span class=""><span class="punctuation">{</span>
<span class="storage type">let</span> rx <span class="keyword operator">=</span> rx.<span class="support function">clone</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="storage type">let</span> t <span class="keyword operator">=</span> rt.<span class="support function">spawn</span><span class=""><span class="punctuation">(</span>async <span class="storage modifier">move</span> <span class=""><span class="punctuation">{</span>
<span class="keyword control">while</span> <span class="storage type">let</span> <span class="support type">Ok</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span> <span class="keyword operator">=</span> rx.<span class="support function">recv_async</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span>.await <span class=""><span class="punctuation">{</span>
<span class="support function">sleep</span><span class=""><span class="punctuation">(</span><span class="">Duration<span class="punctuation">::</span></span>from_secs<span class=""><span class="punctuation">(</span><span class="constant numeric">1</span></span><span class=""><span class="punctuation">)</span></span></span><span class=""><span class="punctuation">)</span></span>.await<span class="punctuation">;</span>
<span class="support">eprintln!</span><span class=""><span class="punctuation">(</span><span class="string"><span class="punctuation string">"</span>worker: {}, data: {}<span class="punctuation string">"</span></span><span class="punctuation">,</span> j<span class="punctuation">,</span> i</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
handles.<span class="support function">push</span><span class=""><span class="punctuation">(</span>t</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="keyword control">for</span> i <span class="keyword operator">in</span> <span class="constant numeric">0</span><span class="keyword operator">..</span>capacity <span class=""><span class="punctuation">{</span>
tx.<span class="support function">send_async</span><span class=""><span class="punctuation">(</span>i</span><span class=""><span class="punctuation">)</span></span>.await.<span class="support function">unwrap</span><span class=""><span class="punctuation">(</span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span>
<span class="support function">drop</span><span class=""><span class="punctuation">(</span>tx</span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
<span class="support function">join_all</span><span class=""><span class="punctuation">(</span>handles</span><span class=""><span class="punctuation">)</span></span>.await<span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span></span><span class=""><span class="punctuation">)</span></span><span class="punctuation">;</span>
</span><span class=""><span class="punctuation">}</span></span></span>
</span></code></pre>
<pre><code dir="auto">worker: 0, data: 0
worker: 1, data: 1
worker: 2, data: 2
worker: 0, data: 3
worker: 1, data: 4
worker: 2, data: 5
worker: 0, data: 6
worker: 1, data: 7
worker: 2, data: 8
worker: 0, data: 9
worker: 1, data: 10
worker: 2, data: 11
worker: 0, data: 12
worker: 1, data: 13
worker: 2, data: 14
worker: 0, data: 15
worker: 1, data: 16
worker: 2, data: 17
worker: 0, data: 18
worker: 1, data: 19
</code></pre>
<p dir="auto">これこれ!</p>
<p dir="auto">これを元に<a href="https://joinplu.me/" rel="noopener noreferrer">実際のアプリケーション</a>に適用してみたらうまくいったっぽい。少なくともローカルでは。このサイトに適用して少し様子を見てみよう。</p>
<p dir="auto">これでいいと思っているわけでもないので、よりよいライブラリー、よりよい書き方があったら教えてください!</p>
]]><![CDATA[『クレイモア』]]>https://blogs.kitaitimakoto.net/~/Apehuci/『クレイモア』と河瀨直美/2022-05-04T17:59:09.284764+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2022-05-04T17:59:09.284764+00:00<![CDATA[<p>八木教広の『クレイモア』を読みました。なんだか最近長めのまんがを一気読みする欲求があって、その一環<sup class="footnote-reference"><a href="#postcontent-1" rel="noopener noreferrer">1</a></sup>。</p>
<p>二律背反がある時に、第三の勢力が現れてそいつが「悪」になってカタルシスの解放が生まれるの、昔は作法と思っていたけど、今はそんな素直に考えられないなあ。</p>
<p>いや、このまんがは面白かったのだけど、一般論としてね。</p>
<div class="footnote-definition" id="postcontent-1"><sup class="footnote-definition-label">1</sup>
<p>他に久保田糸『BLEECH』、田村由美『7SEEDS』、石塚真一『BLUE GIANT』、ジョージ朝倉『ダンス・ダンス・ダンスール』なども読んでる。</p>
</div>
]]><![CDATA[Plumeのでかいリファクタリングをした]]>https://blogs.kitaitimakoto.net/~/Apehuci/Plumeのでかいリファクタリングをした/2022-05-03T16:32:43.934982+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2022-05-03T16:32:43.934982+00:00<![CDATA[<p><a href="https://blogs.kitaitimakoto.net/tag/Plume" title="Plume" rel="noopener noreferrer">#Plume</a> は <a href="https://blogs.kitaitimakoto.net/tag/ActivityPub" title="ActivityPub" rel="noopener noreferrer">#ActivityPub</a> を喋るのだけど、その部分に<a href="https://crates.io/crates/activitypub" rel="noopener noreferrer">activitypub</a> 0.1系とその関連のライブラリーを使っていた。それを<a href="https://crates.io/crates/activitystreams/" rel="noopener noreferrer">activitystreams</a> 0.7系に引き上げるリファクタリングをしていたのだけど、結構時間掛かった。一月からなので四か月だ。</p>
<p>そのプルリクエストがこれ: <a href="https://git.joinplu.me/Plume/Plume/pulls/1022" rel="noopener noreferrer">Upgrade activitystreams to 0.7, again #1022 </a></p>
<p>これを進める上で、結構怖かったので、外部インスタンスとのやりとりのところのテストを追加していった。その際に既存のバグを見付けたりもしたし、自分の変更がうまくいっていなかったらきちんとエラーになって教えてくれるしでとてもよかった。また、型があってもテストが必要なケースがあるよなあという実感も得た。というかまあ、そう思っていたからテストをまず書いたという順番だけどね。</p>
<p>このコンコニで暫く運用してみて、問題なければ本体にマージするつもり。</p>
]]><![CDATA[Plume開発2021]]>https://blogs.kitaitimakoto.net/~/Apehuci/Plume開発2021/2021-12-20T02:25:36.959204+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-12-20T02:25:36.959204+00:00<![CDATA[<p>これは<a href="https://adventar.org/calendars/6469" rel="noopener noreferrer">Fediverse (2) Advent Calendar 2021</a>の20日目の記事です。</p>
<p>昨日はRequinさんの<a href="https://note.com/les_requin/n/nbf8f94b61ea6" rel="noopener noreferrer">自鯖と共に振り返る2021 みたいなの</a>でした。のほほんとしてる間に色々事件(?)があったみたいですが、自分のタイムラインに流れて来ず知る機会がなかったので今更驚いたりしています。ご卒業おめでとうございます。</p>
<h2>Plumeとは</h2>
<p>Fediverse参加のブログエンジンです。記事を投稿したら別のPlumeインスタンスに流れたり、MastodonアカウントでフォローしていればMastodonタイムラインにタイトルとサブタイトルが流れてきたりします(今不具合で流れたり流れなかったりですが……)。</p>
<p>自分とこのPlumeやMastodonなどのアカウントからフォロー、いいね、ブースト、コメントができるのがいいなーと思っていて、密かに<a href="https://note.com/" rel="noopener noreferrer">note</a>の代わりになったらいいのにな、なんて思ったりしています。(金銭の)サポート機能も付けられたら最高ですね。</p>
<h2>Plume開発の一年</h2>
<p>さて、去年のアドカレで <a href="//blogs.kitaitimakoto.net/tag/Plume" title="Plume" rel="noopener noreferrer">#Plume</a> のメンテナーになったことを書きましたが、それからの一年を振り返ってみたいと思います。</p>
<h3>メンテナーになってやる気のあった頃</h3>
<p>今年の最初の三分の一は、開発をどうしたら継続できるかなーなんて考えながら、公式サイトやドキュメントサイトを引っ越して運営の手間を減らしたり、<a href="https://fediverse.blog/%7E/PlumeDev" rel="noopener noreferrer">開発ブログ</a>を継続的に書いて使ってくれる人や開発に参加してくれる人が増えないかなーと考えていたりしました。インスタンスを自分で建てたりしてくれる人まで出てくれて、ありがたい。</p>
<h3>疲れていた頃</h3>
<p>その後の三分の一は、実は結構やる気をなくしており、あんまりPlumeのことはしていませんでした。何かあったわけではなく、何となく疲れたんでしょう。六月、ほぼ公式インスタンスの位置付けにある<a href="https://fediverse.blog/" rel="noopener noreferrer">Fediverse.blog</a>のサーバー運営の人が続けられなくなり、それを引き継いで別のサーバーに引っ越す作業をやりました。Google Compute Engineのインスタンスを立てて引っ越してみたところ、イランの人から「見られなくなった」って報告があって、アメリカ企業のサービスを使うというのはこういうことなのか……と慄きつつ、今は<a href="https://contabo.com/" rel="noopener noreferrer">Contabo</a>というドイツの会社のVPSで動かしています。</p>
<h3>やる気を取り戻した、しかし忙しい</h3>
<p>これでなんかスイッチが入り、また開発を始めます。とは言うものの忙しく、月に数時間程度しか取れない。バグ報告とか改善要望をしてくれたり黙って見守ってくれる人には申し訳ない。一方で自分としては、隙間とやる気が出来た時にちょろっと触るので、結構気軽にしていられました。やっぱり前半は、気負う物があったのだなあ。</p>
<p>そんな一年でした。間もなく次のバージョンをリリースできるはずです。Mastodonのセキュアモードだと投稿が届かなかったのが、このリリースで届くようにもなります。その他右から左に書く言語用の対応とか、一部のページがめっちゃ重かったのの改善とかが入ってます。開発には区切りが付いていて、リリースノートもほぼほぼ書いたので、あとは見直してリリースするだけ……コミケの原稿が終わるまでお待ちください。</p>
<p>気分にムラがあり、それに連動して開発ペースにも波が出来てしまう性格なので、継続的に開発されている方にはほんとに頭が下がります。すごい。</p>
<h2>来年</h2>
<p>の話をすると鬼が笑うと言いますが。鬼の位置付けを知らず、この意味をよく分かってない。</p>
<p>来年は、開発にちょっとでも参加してくれる人が増えるといいなあと思っています。僕一人だと時間が取れず、使ってくれている人に申し訳ない。</p>
<p>それにあたって、HTML、CSS、JavaScriptだけでも参加しやすいようにしたらいいのか知ら、なんて思っています。現在は、HTMLもJavaScriptもRustで書いてコンパイルすることになっており、CSSはSCSSだから書ける人は多かろうものの、動作確認のためには結局Rustの環境を作ってビルドしなければならない。これが中々ハードル高いんだろう、という仮説があります。</p>
<p>でも使う分には使えるはずなので、どこかのPlumeインスタンスにアカウントを作って、記事を書いたり、いいねしたり、ブーストしたり、コメントするようになってくれたら嬉しいです!</p>
]]><![CDATA[自由意思とライブ動画]]>https://blogs.kitaitimakoto.net/~/Apehuci/自由意思とライブ動画/2021-12-18T18:05:47.791607+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-12-18T18:05:47.791607+00:00<![CDATA[<p>ちょっと、時間が無いので、断片的に、メモだけ。</p>
<p>テッド チャン『息吹』で描かれるような、自由意思の話。未来が決定されているということと、人間の自由意志との関係。</p>
<p>ライブ動画をライブで観る時、固唾を飲んで見守っている時と、内容は全く知らないけれど、アーカイブだと知って観ている時。</p>
<p>自由意志の問題をニーチェは乗り越えよと言っているのかも知れないけれど、しかし、ライブ動画をライブで観る時と、アーカイブと知って観る時とでは全く気持ちが違う。</p>
]]><![CDATA[コンビニのお菓子コーナーで考えること - Amazon、Netflix、D2C]]>https://blogs.kitaitimakoto.net/~/Apehuci/コンビニのお菓子コーナーで考えること - Amazon、Netflix、D2C/2021-11-26T10:13:30.725826+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-11-26T10:13:30.725826+00:00<![CDATA[<p>セブン-イレブンにせよ、ローソンにせよ、ファミリーマートにせよ。</p>
<p>お菓子コーナーを眺めると、自社ブランドのお菓子が並んでいることに気が付く。いつからだろう? 数年前には、もっと、色んな会社のお菓子が並んでいた筈だ。お菓子だけでなくドリンクも、自社ブランドが結構増えている。アイスとかも?</p>
<p>自社ブランドのいいところは、第一に安い。他社の類似の物よりも十円、二十円安い。第二に、好みのお菓子やドリンクが揃っている。嬉しい。たまに、オリジナルの方がおいしかったりもするけど(サッポロポテト!)、まあ、大体、満足いく味だ。</p>
<p>オリジナル? そう、セブンのあれは、明確に、サッポロポテト バーベキュー味だ、名前からは伺えないが。味がちょっと違うので、(サッポロポテトを作っている)カルビーが作ってセブン-イレブンのブランドを冠した商品ではなく、セブンが独自に(或いはカルビー以外の所と組んで)作っている商品だろう。</p>
<p>こうしたことは、コンテンツの世界ではずっと問題にされてきた。Netflixが、映画、テレビドラマ、アニメなどの映像作品を作っている各社と契約を交わして、それを配信する。僕等がNetflixへ払ったお金は(間接的に)制作側へと入る。</p>
<p>しかし数年前から、Netflixは制作費を自社で出し、ドラマを撮るようになっている。独占配信だ。監督などの制作チームには、より直接的にお金が入るようになった(のだと思う。知らんけど。)。一方でNetflixは、視聴者との接点も持っている。どんな分野の作品が、どんな長さの作品が、どんな構成の作品が視聴者に好まれるのか、そういったことを知り得る立場にいて、これは制作側やテレビ局などには不可能だ。(部外者なので推測で書いています。)</p>
<p>こうした立場を利用して、彼等は売れることがほぼ分かっている原作を探し出して映像化し、契約により配信権を獲得したほかの作品よりもよりよい位置に置くことで実際に売ることができる。(法律に触れるリスクも出て来るけど。)これは健全なことなんだろうか? Netflixの名前を出しているけど、HuluだってAmazonプライム・ビデオだって、事情は一緒だろう。</p>
<p>ところで、僕は現在<a href="https://corkagency.com/" rel="noopener noreferrer">株式会社コルク</a>に勤めていて、だからこの話題は結構危ない。出版の世界の話はしないでおく。気になる人は想像してみてください。</p>
<p>コンビニの話に戻ると、同じことがお菓子についても行われていたのではないか、と最近ようやく思い至った。全国チェーンのコンビニは、売れ筋商品を占う膨大なデータを持っているわけなのだ。そして、自社ブランド商品を少しだけ安価にすることで競争力を持たせられる。何なら、今は、類似商品を置いてさえいないように思う。自社ブランドのお菓子に好みの商品が入っているのは、当たり前だったのだ、だってそういうのを自社ブランドから出しているのだから。</p>
<p>お菓子の製造だけを担い、販売はコンビニやスーパーなどの小売りに任せている会社は、中々苦しい思いをしているのではないか。自分たちが苦心して探り当てた人気商品をあっさりとコピーされてしまう。</p>
<p>このことに気付いたのは、木村石鹸の社長である木村祥一郎さんのブログ記事「<a href="https://note.com/yudemen/n/n0ea46731aea0" rel="noopener noreferrer">顧客接点を持つ流通がPBでどこかで見た商品を出す問題について</a>」を読んだからだった。小売りとしてのAmazonが、人気商品の類似品を作って出していることについての話だ。</p>
<p>これらをでも、僕は否定し切ることができない。だって消費者にとってはいいことばかりだ。安い。好みにフィットした商品・作品が作られる。それが加速する。自由主義経済の中で、細かな消費者行動データを多量に取得できるとなれば、当然起こることだ。それが行き過ぎないようにする法律は存在しているのだから、今現在行われている程度は合法で、大まかに合意された倫理の範囲内だ、という形になる。</p>
<p>でも、この流れにあまり載っていないように見える物もある。コンビニで言うとデイリーヤマザキ。山崎製パングループの運営で、基本的には既存の物を仕入れて売っているけど、パンは店内で焼いたり、山崎製パンの物を仕入れたりして、強みとしている。寧ろパンを売りたくて店を出し、店に来る理由を作るために他の商品を仕入れているとも見ることができる。(そんなことはない、というか総合的に考えて運営しているだろうけど。)</p>
<p>コンソールゲームはどうなんだろう? 僕の知っているのは古くて、Gamecubeとかぐらいで止まっているんだけど、ゲーム販売店がゲームを作っているという印象はない(調べてはいないので、本当はあるのかも。)。でも今はネットワークでゲームを買う時代だろうから、DeNAとかはやっているのか? Epic Gamesとか気になるけど、どうなんだろう。ゲームは、作ろうと思ってから出来上がるまでに時間もコストもかかるというのが、つまり量産できないという性質がこの傾向を抑えているのかも知れない。</p>
<p>話を戻して、今からコンテンツをやる人達は消費者との接点を押さえに行くだろうし、お菓子を作る人は店舗も込みでビジネスモデルを考えるだろう。最初は生産だけをやっていても、いずれそこを押さえに行くことはどうしても視野に入ってくる。(繰り返すが出版関係はここでは何も言わない。)</p>
<p>そこでD2Cという言葉を思い出す。Direct to consumer、つまり生産者が直接消費者と繋がってしまおうという動きだ。これは、プラットフォームを迂回して消費者との接点を直接持ってしまおうということになる。インターネットのおかげで現実的になったビジネスモデルだなと思える。D2Cは生産者にとって、プラットフォームを目指さないのであれば必然的に取らざるを得ない戦略に見える。</p>
<p>消費者にとってはどうだろう? 今のところ、動画もお菓子も、安くなって、消費者にとっていいことのように思える。でも、彼等が市場を押さえたら値上がりしてくるかも知れない。してこないかも知れない。偏りのある物ばかり提供されるかも知れない。それで別にいいかも知れない。</p>
<p>D2Cとは関係ありそうなトピックだなと思いつつ、この辺はあまり考えていないのでもうちょっと時間を掛けてみようと思う。</p>
]]><![CDATA[『Every Layout』を読んだ]]>https://blogs.kitaitimakoto.net/~/Apehuci/『Every Layout』を読んだ/2021-11-26T01:49:11.317920+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-11-26T01:49:11.317920+00:00<![CDATA[<p>『<a href="https://www.borndigital.co.jp/book/24538.html" rel="noopener noreferrer">PDF版 Every Layout モジュラーなレスポンシブデザインを実現するCSS設計論</a>』を読んだ。</p>
<p>とてもよい。このよさは監訳者であるyuheiさんのブログ記事「<a href="https://yuheiy.hatenablog.com/entry/2020/05/06/213311" rel="noopener noreferrer">CSSにおける汎用化の先送り、ユーティリティファーストCSS、レイアウトプリミティブ</a>」でよく言い表されていて、</p>
<blockquote>
<p>パターンの収集という意味でレイアウトプリミティブは絶妙である。ウェブデザインの中で無意識的に繰り返されていたようなレイアウトの手法を拾い上げ、極めて汎用的な形式知に変換することによって、思いもしない抽象化の可能性が提示されたように感じた。</p>
</blockquote>
<p>分かる。</p>
<p>今年の前半ぐらいまで割とHTMLマークアップの仕事も多く、「あーこのやつ、何度も書いてるよなー」と感じながらページを作っていた。しかしそれは、ボタン、とか、「画像+テキストの組み合わせ」とか、セクション、とかいうコンポーネントの粒度ではどれも似ているけれど違うのだ。汎用的にコンポーネントを作って再利用しようとしても、パラメーターが増えてしまって、それなら毎度CSS書いても同じじゃん、となる。なーんか、やりようはあるっぽい雰囲気なんだけど、どうもうまい方法が見えてこない──はっきり言葉にしてこう考えていたわけではないけれど、もやもやとこう感じていたのだなと本書を読んだ今では思う。あと一押しだったのだ。こういう感じの人達は結構多かったのではないか、だから、日頃「なーんか似たようなことやってるなー」と感じているマークアップエンジニアは、この本を読んで「あと一押し」を獲得できる人と思う。</p>
<p>リンク先の記事に使われている画像を見てもらうのが早いのだけど、よくウェブページで使われるレイアウトを</p>
<ul>
<li>Stack(縦に等間隔に並べる)</li>
<li>Center(水平方向中央揃え)</li>
<li>Cluster(タグ一覧みたいに、複数行に跨るコンポーネント一覧)</li>
<li>Sidebar(広い画面ではサイドバー、狭い時は縦並び)</li>
<li>Switcher(広い画面では横並び、狭い時は縦並び)</li>
<li>:</li>
<li>:</li>
</ul>
<p>などの「レイアウトプリミティブ」の組み合わせで大体作れる、と喝破して、それを実演して見せているのが素晴らしい。一つのコンポーネントやセクションに見える物も複数のパターンの組み合わせで出来ている。</p>
<p>素晴らしい、と言うか、これで一気に目が開かれた思いになった。これまでデザインを「視る」ためのフレームが自分の中に無かったのだ、と気が付かされた。これらを一度インプットしてしまえば、デザインカンプを貰った時に、これらのパターンに分解して視ることができるようになる。</p>
<p>こうして見ると、<a href="https://chakra-ui.com/" rel="noopener noreferrer">Chakra UI</a>の<a href="https://chakra-ui.com/docs/layout/stack" rel="noopener noreferrer">Stack</a>とか<a href="https://chakra-ui.com/docs/layout/box" rel="noopener noreferrer">Box</a>なんかが愛おしく見えてくる。</p>
<p>この本の構成要素は、</p>
<ul>
<li>よりよいCSSの書き方の原則</li>
<li>レイアウトプリミティブのカタログ</li>
<li>レイアウトプリミティブの作り方(CSSコード)</li>
</ul>
<p>になっていて、僕は主に二つ目に感銘を受けたわけだけど、一つ目の書き方原則も中々いいことが書いてあって、セクションとかコンポーネントごとにクラス名を決めて、SCSSの入れ子でその中で主に各コンポーネントをレイアウトしていくやり方が何故よくないのか、といったことを説得力を持って書かれていて説得された(それがいいか悪いかということを考えたことすらなかった)。</p>
<p>三つ目の実際のCSSコードも、机上の空論じゃないことがはっきり伝わってくるし、知らないCSSテクニックも沢山あって単純に読み物として読んでいて楽しい。</p>
<p>これはマークアップする人みんな読んでほしいなーと思う。</p>
<p><a href="https://www.borndigital.co.jp/book/24204.html" rel="noopener noreferrer">印刷版</a>、<a href="https://www.amazon.co.jp/dp/B09LQNQ7CW/" rel="noopener noreferrer">Kindle版</a>、<a href="https://www.borndigital.co.jp/book/24538.html" rel="noopener noreferrer">PDF版</a>が発売されていて、僕はPDF版で買った。やっぱり標準化されたフォーマットは嬉しい。今時PDFなら、大体のソフトウェアで、メモを取りながら読むこともできるしね。</p>
]]><![CDATA[cargo installでもCargo.lockを使う]]>https://blogs.kitaitimakoto.net/~/Apehuci/cargo installでもCargo.lockを使う/2021-11-26T01:09:08.382708+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-11-26T01:09:08.382708+00:00<![CDATA[<p><a href="https://fediverse.blog/" rel="noopener noreferrer">fediverse.blog</a>で動かしているPlumeは、ソースコードからビルドしている。つまりサーバーでソースコードをチェックアウトしてきて</p>
<pre><code>% cargo install
</code></pre>
<p>を実行している。</p>
<p>この時、知らなかったのだけど、(<code>cargo build</code>とは違って)Cargo.lockは無視されて、Cargo.tomlだけが使われるみたいだ。強制的にCargo.lockを使わせたい時には、 <code>--locked</code> オプションを使う。</p>
<pre><code>% cargo install --locked
</code></pre>
<p>Cargoのリポジトリーに<a href="https://github.com/rust-lang/cargo/issues/7169" rel="noopener noreferrer">イシュー</a>が上がっていて知った。</p>
]]><![CDATA[ひたすら寝ていた]]>https://blogs.kitaitimakoto.net/~/Apehuci/ひたすら寝ていた/2021-11-20T23:04:09.629709+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-11-20T23:04:09.629709+00:00<![CDATA[<p>金曜日(2021-11-19)に、二回目のファイザー製COVID-19ワクチンを打って、夜はもう異様に眠くて、熱は出ていたんだか出ていなかったんだか分からないけど解熱剤を飲んで、寝た。</p>
<p>目が覚めてもご飯を食べて、解熱剤を飲んで、また寝た。</p>
<p>ワクチンのせいで熱が出たのかどうかは分からないうちに解熱剤を飲んでみた。のでワクチンのせいで眠たいのか解熱剤のせいで眠たいのか分からないけど、もうひたすら寝ていた。</p>
<p>今は別に寒気も無いから、これで落ち着いたのかな。売った方の腕は鈍い痛みのようなものは残ってる。</p>
]]><![CDATA[自分が作るわけじゃない物のデザインをするのが嫌いである]]>https://blogs.kitaitimakoto.net/~/Apehuci/自分が作るわけじゃない物のデザインをするのが嫌いである/2021-11-12T19:53:09.906848+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-11-12T19:53:09.906848+00:00<![CDATA[<p>自分が作るわけじゃない物のデザインをするのが嫌いである。</p>
<p>それは何故だろう。それがおこがましい行為に思えるから、と思っていた。しかし、フィードバックが少ないからではないか、と思い付いた。</p>
<p>自分がデザインをした物を作った人から話を聞くことはできる。ソースコードを見ることもできるだろう。しかし、自分のデザインに従って実装し、何か変だなと感じる、間違ってるじゃないかと憤る、中々いいなと喜ぶ、実装で得た考えを元にデザインの方を変える……そうしたことが、できないのだ。自分が作るわけじゃない物のデザインでは今一本気になれないのも、そういうことから<span>—</span>レスポンシビリティの欠如から<span>—</span>来ているのかも知れない。</p>
<p>ああそうか、僕は何かを作る時に自分に感情が生まれるのを、大事にしているのだな。</p>
]]><![CDATA[2021-10-17]]>https://blogs.kitaitimakoto.net/~/Apehuci/2021-10-17/2021-10-17T16:22:05.971406+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-10-17T16:22:05.971406+00:00<![CDATA[<p>夜目を覚まし、Twitterでリアルタイムで大体読んでいたんだけど終わりまでは読んでいないことを思い出し(ツイ4でNobelの新作が始まったので思い出した)「<a href="https://sai-zen-sen.jp/comics/twi4/moutele/" rel="noopener noreferrer">妄想テレパシー</a>」を最後まで読む。夕食を取った後『<a href="https://booklog.jp/item/1/B00P7C2D1A" rel="noopener noreferrer">夜と霧</a>』を読み始める。序盤で既に色々考える。自分はこの状況に放り込まれたらどうできるだろうか、とか、何が悪いのだろうか、とか、人間とは、とか。</p>
]]><![CDATA[SendGridのAPIキーが消失していた]]>https://blogs.kitaitimakoto.net/~/Announcement/SendGridのAPIキーが消失していた/2021-08-12T15:53:27.576751+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-08-12T15:53:27.576751+00:00<![CDATA[<p>これですけどもね、
<a href="https://blogs.kitaitimakoto.net/%7E/Announcement/%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%83%AA%E3%82%BB%E3%83%83%E3%83%88%E6%A9%9F%E8%83%BD%E3%81%8C%E5%8B%95%E4%BD%9C%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%9B%E3%82%93%E3%81%A7%E3%81%97%E3%81%9F" rel="noopener noreferrer">パスワードリセット機能が動作していませんでした</a>
変だなと思ってSendGridのAPIキーの設定を見たら、APIキーがすべて焼失していました。多分、最近セキュリティアップデートがあったから、その際に古いやつをSendGridが消してしまったのではないかと思います。いやあ、メールとか見てなかったもんな……。</p>
]]><![CDATA[パスワードリセット機能が動作していませんでした]]>https://blogs.kitaitimakoto.net/~/Announcement/パスワードリセット機能が動作していませんでした/2021-08-12T15:52:00.610392+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-08-12T15:52:00.610392+00:00<![CDATA[<p>パスワードリセット機能が暫く(二か月ぐらい?)動作していませんでした。先ほど修正しました。失礼しました。</p>
]]><![CDATA[映像研には手を出すな!]]>https://blogs.kitaitimakoto.net/~/Apehuci/映像研には手を出すな!/2021-04-11T04:43:59.599838+00:00北市真https://blogs.kitaitimakoto.net/@/KitaitiMakoto/2021-04-11T04:43:59.599838+00:00<![CDATA[<p><a href="./%E5%A4%AA%E9%99%BD%E3%81%AE%E5%A1%94" rel="noopener noreferrer">太陽の塔を読んで</a>頭の中で何かの弾みが付いて考え続けていたら、情けない物をそのまま描けるのは才能だなと辿り着いて滝本竜彦の『NHKにようこそ!』を思い出した。ところからの『映像研には手を出すな!』である。</p>
<p>『映像研』を知っている人にはこの流れは分からないと思う。既に知っている側に回った僕にも分からない。『映像研』はテレビアニメが放映されていて、その頃は観てない(し今も観ていない)がポッドキャストの「Rebuild」で度々触れられていて、そこからある種の想像はしていた。オタクっぽさを過度に卑下するでもなく、消臭するでもなく、そのまま描いているんだな、という想像を、「Rebuild」を聴いてしていたのだ。そう考えると、『太陽の塔』『NHK』からの流れで読みたくなるのは分かる気がする。勿論、兼ねてから「評判いいし、いつか読まねばな」リストに入っていたということは大きい。</p>
<p>さて面白かった。物を作るという時のバランス感覚を、三人のキャラクター間の綱引きとして描いていて何度も泣きそうになった。</p>
<p>まだ終わっていなくて嬉しい、まだずっと読み続けていたい。</p>
]]>