※ IETF 116などの定期的に開催されるin-personな会合をこのブログでは “IETF Meeting” と呼びますが、正式名称ではない可能性があります。正式名称があったら教えてください。ちょっと探したけど総称っぽいものが見付かりませんでした。
IETFは、"Internet Engineering Task Force" の略で、インターネットの標準を決める団体です。ざっくばらんに言えば、RFCを出しているところです。
IETFが何なのかについては、既に良い説明があるのでそちらを参考にするのがいいでしょう。以下にリンクを貼っておきます。
さて、そんなIETFの116回目のMeetingが横浜で行われるとのことなので参加してきました。ただ、僕は都合上Hackathon(日曜)と木曜日のみの参加でした。
まずはIETFがどのような構造を持つ組織で、どのように議論が進んでいくのかを頭に入れておくと、議論が現在どういう状態にあるのかを把握でき、理解の助けになります。以下のリンクを読み、そのあたりの勉強をしました。
次に、自分の興味がある分野のdraftなど、Agendaに記載されている資料について読んでおきます。IETFの会議は、既にMailing listである程度議論されているdraftの内容について実際に対面で意見を交わすという場なので、draftは読んでおくべきでしょう。
以下、メモは常体です。正確性の保証はありません。
https://wiki.ietf.org/en/meeting/116/hackathon
Hackathonは特定のprojectには参加せず、自分がやっているcurlのHTTP/3版ビルドをメンテナンスしたり、QUIC実装のデバッグをしたりしていました。
https://datatracker.ietf.org/meeting/116/session/quic/
ACK_FREQUENCY
frame とか IMMEDIATE_ACK
frameとかadditional_schema
についてRELIABLE_RESET_STREAM
frame, that resets a stream, while guaranteeing reliable delivery of stream data up to a certain byte offsethttps://datatracker.ietf.org/meeting/116/session/moq/
むずかしい!
メディア転送、既にあるWebTransportではなくMoQ(MoQTransport)を定義したいモチベーションとしては、WebTransportはHTTP/3の上にあるプロトコルなので、映像配信をするのにサーバーがHTTP/3を解釈する必要があり、そうじゃなくQUICの上で直にメディア転送ができると嬉しいということらしい(会場で又聞きした)
https://datatracker.ietf.org/meeting/116/session/acme/
dns-account-01
を定義するもの
.onion
domain に対してもACMEによる証明書の自動発行が可能になるようにしようというものIETF、インターネットの標準化について「興味はあるし、楽しそうだけど敷居が高くて、自分はまだそのレベルじゃないな」と尻込みしている人が多いのではないかと思います。確かに、議論の内容はインターネットの最先端についてなので予習しておかないとついてはいけませんし、しかし予習したからといってついていけるわけでもないですし、何より英語でのやりとりを理解する必要があります。ただ文字起こしがあるので、あとからゆっくり読み返すことはできます。
しかし、IETFそのものが初心者を歓迎しているイベントです(そう感じました)。理由は、参加回数が5回未満であれば名札に “NEW ATTENDEE” というリボンを付けることができます。初参加者向けの “New Participants’ Social Hour” というイベントもあります。つまりそのようなNewbieに対するサポートを行うという意識が参加者の間にはあるということです。実際、わからないことを聞いても突き放されることなく、丁寧に教えていただけました。
ただやっぱり、趣味で行くにはEarly Birdであっても$700というのは厳しいものがあります。これについては、(レポートなりを書くことで)業務扱いとして参加費を出してくれる企業が増えてくれることを願うばかりです。特に「若い人達が流入してくれないか」というのを懇親会ではよく耳にしましたし、そのためには若者の手を引いてくれる先輩の存在が、そしていずれそのような先輩となってくれるような、標準化の分野に興味のある人が参加しやすいような土壌をつくることが重要です。インターネットは、欧米の大企業が作っているものを享受する、というものではなく、人類全体で作っていくものです。インターネット上でサービスを提供している企業であれば、インターネットをより良くしていくための活動に対しては支援を惜しむべきではありません。それこそ、社内で採用されているプログラミング言語やフレームワークのカンファレンスに対する参加支援と同じような流れで、IETF Meetingの参加費を支援する企業が増えてくれると嬉しいですね。毎回とはいかないまでも、せめて国内開催の場合は旅費交通費を含めた支援がされるのが望ましいのかもしれません。
そして、お金を払って参加するのであれば、何か目標を自分に課すといいかもしれません。議論の様子や発表される資料は全て公開されています。それでも現地に参加するのは、実際に「インターネット」に関わっている人達に会えるからです。実際僕も、今回のIETF Meetingで「QUIC working groupのchairに話してQUIC開発者が集まっているSlackに招待してもらう」ことを目標として参加し、達成しました1。現地参加するのであれば、現地参加だから意味のある目標をひとつ決めて参加するのがいいと思います。
それと、チケットはWeek Pass(全日)を買っておくほうが絶対に良いです。僕は日和ってAgendaが確定した後にOne-Day Passを購入しましたが、自分の興味のある分野のMeetingが1日に集中することは本当にまれですし、一旦Agendaが確定した後に突然Meetingが生えたりすることもあります。
(ついでに言うと、1日しか参加しないにしても、Agendaの決定を待たずに購入するべきでした。参加当日、正確には受付時に判明したのですが、One-Day Passを購入する段階ではどの日に参加するかを選ぶものではなく、受付のタイミングでどの日に参加するか伝えるというものでした。上の写真の名札にある “THURSDAY” はその場でスタンプされたものです。つまりどういうことかというと、Early価格で買えたのにAgendaを待ってたからLate価格になってしまった……という話です。このシステムが116特有のものか、ずっとこのシステムなのかはわかりませんが。)
僕もこの界隈に足を踏み入れたばかりなので右往左往していますが、それでも参加して楽しかったし、今になっては全日程参加しておけばよかったと思っています。QUICというプロトコルに関しての活動をしているタイミングで、国内でIETF Meetingが開催されるというのは本当に幸運だったと思います。
次回、117はサンフランシスコで開催されるようです。時差が厳しい問題ではありますが、まずはRemote参加をしてみるというのは検討してみてもいいのではないでしょうか。僕も参加するとしたらリモートになるでしょうし。
https://www.ietf.org/how/meetings/117/
もちろんmailing list経由で招待してもらうこともできると思います。しかしこんな良いタイミングでIETFがあるなら直接、と考えました。 ↩
Rubyアソシエーション開発助成 2022年度の僕のプロジェクトの成果としては、以上の通りとなります。このブログは最終成果報告ではなく、個人的なふりかえりなどを書いています。
感想としては、「勉強にはなったが、しんどかった」です。いくら既存の実装を移植するタスクとはいえ、いくらPythonがRubyと似た言語であるとはいえ、移植作業はとても困難1でした。単純に行数が多いというのもその理由のひとつですが、特に移植が大変だった tls.py
と connection.py
では、さらに大きな問題がありました。
まずは、処理対象となるデータが暗号化されていることです。テストケースが落ちているとき、どこから実装が誤っているのかの調査が困難でした。とにかく大量のdebug printを出したり、PyCharmのdebuggerとdebug.gemによるstep実行を1行ごとに交互に進め合ったりするなどしてなんとかしました。その結果、基礎的な暗号技術の知見がないために生まれたバグが原因だったり、call stackの奥深くでtypoしていたりして、自分の実力を思い知らされました。
次に、暗号化に関連しますが、OpenSSL binding API の問題です。PythonもRubyも、暗号化や、鍵交換に関わる処理はOpenSSLを利用しています。Python、aioquicだとpyca/cryptographyが、Rubyだとopenssl gemがOpenSSLのAPIを利用するのに使われますが、この2つのライブラリ間で、OpenSSL APIの抽象化度合いが異なります。なのでOpenSSL APIを使う部分の移植については、まずPython側の実装が最終的に何のOpenSSL C APIを呼んでいるかを突き止め、それがopenssl gemではどんなAPIになっているかを調べる、という手順が必要でした。
言ってしまえば、この分野に首を突っ込むにはまだまだ知識が不足していることを痛感させられた、ということです。
一方、そのような難しいことに取り組むことにあたって、やはり「やります!」と宣言して締め切りが生まれるのは、自分の手を動かすことへの途方もないくらいの後押しになりました。採択されなくても進めるつもりではありましたが、その場合は倍以上の時間がかかるか、そもそも諦めていたでしょう。
また、この取り組みにあたって、どうせならと型定義も書くことにしました。型定義(RBS)を書くことで、補完や警告による恩恵を受けることができました。ただ、nil checkをした後でもnilによる警告が出たり、長大なファイルになってくると補完候補が出てくるまでにふた呼吸必要になったりと、まだまだこれからという印象は否めませんでした。型定義について、これからはなるべく書いていこうと思います。
このプロジェクトを進めるにあたって新規に購入したり、既に買っていたけど改めて読み直したりした本が以下です。
https://www.oreilly.co.jp/books/9784873119328/
このプロジェクトをやる人間が読むのが「入門」はないだろうという感じではありますが、Pythonについて体系的に学んだことがなかったので購入しました。 この本を読むまで知らなった文法が多々あり、もちろんそれはaioquicでも使われている場面がそこそこあったので、読んでおいてよかったです。
https://www.lambdanote.com/products/tls
SSL/TLSそしてOpenSSLに関しては、とりあえずはこの本を読んでおいて間違いないと考えており、以前から所有していました。実装にあたってTLS 1.3を解説した新章がその助けになりました。
https://www.shoeisha.co.jp/book/detail/9784798171418
TLSの実装の際に、より役に立ったのはこちらの本でした。「プロフェッショナルSSL/TLS」のほうはSSL/TLSがどのようなものであるかの説明であるのに対し、こちらの本はOpenSSLのAPIを使って実際に通信をするためのコードが出てきたりと、より実装寄りの本となっています。
https://www.shoeisha.co.jp/book/detail/9784798148816
TLSが通信を暗号化するために使用している技術について学ぶことができる本です。まだ読み終えてはいませんが、そもそもにTLSを移植しようという人間が、その内部で使われている暗号技術に関して無知というのはいかがなものかと思い読んでいます。
https://www.ohmsha.co.jp/book/9784274065736/
これもまだ読み終えられていません。なぜこの本を買ったかというと、OpenSSLについての知識が足りないなと思ったためです。この本ではOpenSSLの0.9.6について解説しており、現在OpenSSLの最新リリースは3.1.0です。なので今となっては古い本となってしまいますが、そもそもOpenSSLそのものを解説した(日本語の)本というのは本当に少ないので、まずはこれを読もうと思っています。
僕の理解を書きます。なので誤っているかもしれません。
QUICについては、IETFのQUIC working group(以降WGなどと略します)で議論されており、現在activeなDraftは8つあります。またQUICのWG以外でもQUICが関連しているRFCやDraftがあります。例えば最近はQUIC上で映像や音声の転送を行うための仕様について議論するMedia Over QUIC WGが盛り上がっている2ようです。
QUICプロトコル自体については、Version 2についてのdraftが出ています。Version 1からの変更点は、まずversion値が変更されます。暗号化について定めされているいくつかの初期値も変更されます。そして、そもそもQUICのどのversionで通信を行うのかを合意するversion negotiationをどのように行うかについてもdraftになっています。
興味深いのは、これまでのQUIC v1ではversionの値として 0x00000001
が使用されますが、QUIC v2ではその値に 0x6b3343cf
が使われることです。これは硬直化を防ぐのが目的だと記載されています。硬直化とは、通信を処理するプログラムの古い実装が、新しい仕様での通信内容を解釈できずに通信が阻害されてしまうことを指します。既存の例を挙げると、TLS 1.3では、自身のバージョン値として TLS 1.2の値を使用して通信することになっています34。そもそもに、QUIC v2がそのような硬直化を防ぐためにRFCとなる作業が進められている(ように読める)ものなので、QUIC v1がもう古くなって脆弱だ、ということはありません。それはdraft-ietf-quic-v2-10にも
QUIC version 2 is not intended to deprecate version 1.
と明記されています。
他にもdraftになっているものはいくつかありますが、3月末に開催されるIETF 116 YokohamaにおいてAgendaにあるのは以下の3つです。(QUIC v2についてはAgendaには載っていません)
Media Over QUICのほうに目を向けてみると、mailing listの投稿がとても活発で追いかけるのが大変なのですが、下記のyukiさんのまとめによれば、Warpをbase draftとして議論が進んでいるようです。まとめではdraftの番号が02となっていますが、今年3/13に04が出ています。
おそらくIETF 116においてもこれについてのミーティングが行われるのだと思いますが、今これを書いている段階ではまだAgendaがなにもありません。
プロジェクトとしては一区切りしましたが、移植作業そのものはまだ途中です。引き続きQUICの実装に取り組むつもりです。が、とりあえず迫っているRubyKaigiの準備があるのでしばらく実装についてはゆっくりになると思います。というかまあ、プロジェクト期間中は結構無茶な開発をやっていたので、しばらくはペースが落ちると思います。
ここで書きすぎると、RubyKaigiで話す内容がなくなってしまうのでこのくらいで。
メンターとして面倒を見てくださった笹田さん、そしてそもそも僕のproposalを採択していただき、このような機会をくださったRubyアソシエーションさんに感謝します。本当にありがとうございました。
開発は基本的にUbuntuマシンにSSHして行っていました。これを、福岡Rubyist会議03や鹿児島Ruby会議02のときには飛行機に乗ることもあり、MacBook上に開発環境を構築しようとしましたが、しばらく頑張ってもaioquicのテストをApple SiliconのMac上でネイティブ実行することができずに諦めました。OpenSSL周りに問題がありそうだというところまではわかったのですが……とはいえ移動中にまともなコードは結果的に書けなかったので、これは些細な問題でした。 ↩
Media Over QUIC、実はあまり追い掛けていなかったので調べながら書いています。いや、他のRFCやdraftについても調べながら書いています。 ↩
プロフェッショナルSSL/TLS 付録A TLS 1.3 A1.1.1 Record Structure 参照のこと ↩
本当は30周年LTをする前にこの記事を公開したかったのですが、色々あって今になりました。
昨年末から、Rubyアソシエーション開発助成の対象として採択され、QUICプロトコルをRubyにて実装する活動をしています。具体的には、PythonによるQUIC実装 aioquic をRubyに移植するということを行っています。
“移植"とはいっても、aioquic の完全な移植を作成するつもりはなく、あくまでもこれはQUICの実装の感じを掴むために行なっているものです。現状、QUICの実装として主要な部分と言える、以下の移植を終わらせています。
また現時点では aioquic/quic/connection.py の移植作業を行っています1。冒頭の画像は、GitHubにpushしていないものも含めた現時点での行数をtokeiによって集計したものです。
Ruby 30周年記念イベントにおいて、これら数千行のPythonのコードを読み、Rubyへと書き換えていくなかで、RubyにもPythonのこういう機能があれば便利だと思う、という意図のLightling Talkを行いました。
鹿児島では、QUICの簡単な説明と、発表時点での実装においてどこまでのことが可能なのか実際に動かして説明し、今後の展望について話そうと考えています。
これの移植がうまくいかず、テストケースが通ったらこのブログを書こうと考えていましたが、結局まだ完走できていません。 ↩
Ruby界隈における「blade」といえば、Rubyの各種メーリングリストのアーカイブを提供している、 http://blade.nagaokaut.ac.jp/ruby のことを指します。
blade Ruby の各種メーリングリストのアーカイブ。
これは長岡技術科学大学の原先生という方が運営されていたようなのですが、2022年8月頃にサーバーが壊れてしまいました。
Rubyist Hotlinks 【第 21 回】 原信一郎さん
そこで、hsbtさんが取得していたバックアップ、ko1さんやshugoさんの保持していたデータから再構築されたのが https://blade.ruby-lang.org です。
さて移行されました、めでたしめでたし……ではあるのですが、インターネット上に残る blade.nagaokaut.ac.jp
は自動的に blade.ruby-lang.org
へ移動したりはしてくれません。URLは機械的に置き換えることができるので、手でURLを編集してしまえばいいのですが、やっぱり手間です。
そんなわけで、自動的にリダイレクトしてくれるChrome拡張機能を作りました。
Manifest V3で作成したのが仇となったのか、Firefoxではmanifest.jsonが不正として扱われてしまっています。EdgeはChrome web store経由で拡張機能をインストールできるんですね。
Chrome拡張を作成するのは、以下の記事たちを参考にしました。
ぶっちゃけ、ただURLを機械的に置換してリダイレクトする、なんてことをしてくれるのは既存のChrome拡張でもあるでしょうし、Tampermonkey(Greasemonkey)でも可能です。
という訳で、Tampermonkeyで使用できるUserScriptを以下に用意しました。リポジトリにも含めています。
https://github.com/unasuke/blade-redirector/blob/main/misc/blade-redirector.user.js
// ==UserScript==
// @name Blade ruby mailing list archive redirector
// @version 0.1.0
// @description Redirect from blade.nagaokaut.ac.jp's ruby-core and ruby-dev mailing list archive that's no longer available to blade.ruby-lang.org that's the alternative.
// @author unasuke (Yusuke Nakamura)
// @match http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/*
// @match http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/*
// @icon https://avatars.githubusercontent.com/u/4487291?v=4
// @updateURL https://github.com/unasuke/blade-redirector/raw/main/misc/blade-redirector.user.js
// @downloadURL https://github.com/unasuke/blade-redirector/raw/main/misc/blade-redirector.user.js
// @supportURL https://github.com/unasuke/blade-redirector
// ==/UserScript==
(function () {
"use strict";
const dialog = (url) => {
const anchor = `<a href="${url}">${url}</a>`;
const elem = document.createElement("div");
elem.innerHTML = `Redirect to <pre style="display: inline-block">${anchor}</pre> after 3 seconds.`;
elem.setAttribute("style", "font-size: 20px; font-weight: bold");
return elem;
};
const location = document.location.pathname;
if (
location.startsWith("/cgi-bin/scat.rb/ruby/ruby-dev/") ||
location.startsWith("/cgi-bin/scat.rb/ruby/ruby-core/")
) {
const newPath = location.replace("/cgi-bin/scat.rb/ruby/", "");
const newUrl = `https://blade.ruby-lang.org/${newPath}`;
const htmlBody = document.getElementsByTagName("body")[0];
setTimeout(() => {
htmlBody.prepend(dialog(newUrl));
}, 500);
setTimeout(() => {
window.location.assign(newUrl);
}, 3500);
}
})();
じゃあなんでChrome拡張なんて作ったのか?それは……Chrome拡張機能を作ってみたかったからです。
失われた「フリーソフト」の哀愁と、今を生きる開発者への願い。 - Zopfcode とインターネット上の反応を読んで、自分がコードを公開する場合、しない場合それぞれの理由を現時点で書いておきたいなと思ったので、書きます。
例えば便利なライブラリを思いついて実装したとします。そのライブラリを実際に使う場合、実装したコードがある手元のマシンであればそのまま使用することができますが、どこかのクラウドで動かしてるWebアプリで使用したい場合はどうすればいいでしょう?
Repositoryが公開されているのであれば、大抵のパッケージマネージャーではgit repositoryのURLを指定することでインストールができるでしょう。ではそのrepositoryがprivateの場合はどうでしょうか。readを許可したPersonal Access Tokenを発行して適切に設定するなどの手間が発生します。面倒ですね。
GitHubにコードを公開することで、自分がどんな言語をよく書いているのか、どのような技術に触れたことがあるのか、などという情報が伝わりやすくなります。
また、今でこそ立場的に採用に関わることはありませんが、もし採用に関係する立場になったとして、その人が公開しているコードを見ることで得られる情報はとても多いでしょう。これは以下のonkさんの記事に、どのような点を見ているかということが詳しく書かれています。
書類選考時に見ているポイント - id:onk のはてなブログ
僕の意見ですが、採用選考の状況においてはGitHubアカウントがない、もしくはあっても公開されているリポジトリがないから減点、ということではなく、あったら参考になる情報が増えるので基本的にプラス、というのがより正しいと思っています。公開しているコードが明らかにどこかから剽窃したものだったり、ハラスメント行為にあたるような内容が含まれていたりしない限りは、GitHubアカウントの有無、公開リポジトリの有無やその数で採用の結果が左右されることはないと考えています。
企業が提供しているサービスのコードを原則公開しないように、これは公開するとちょっとマズいことがあるな、というものは公開しません。表現としては「公開できない」のほうが正しいでしょう。僕に経験はありませんが、例えば発見した脆弱性の概念実証コードもこの分類になると思います。
裏を返せば、僕は公開できない明確な理由がない限りはコードを公開するようにしています。
今でこそGitHubの無料プランであってもprivate repositoryは作り放題になっていますが、2020年までは有料プランを契約していないとprivate repositoryを自由に作成することはできませんでした。
GitHub is free for teams | The GitHub Blog
他にもTravis CIやCircleCIではpublic repositoryであれば無料で計算資源を使えたので、コードを公開することは財布にも優しいという時代がありました。今ではGitHub Actionsがありますが、これもprivate repositoryでは使用できる時間に上限がありますね。
これは気持ちはわかるものの、それは公開しない理由にはならないというのが僕の意見です。
そもそも、自分の書いたコードが綺麗である、と胸を張って言える人というのはいるのでしょうか。そして、たとえ公開されていてとても広く使われているコードであっても、誰が見ても汚いと判断されるようなコードはあるはずです。近年であれば静的解析ツールやLintも充実しているでしょうし、これらは普段のコーディングにおいてもミスを防いでくれるので、導入しない理由はありません。そしてLintを導入している時点で、コードの品質はある程度保たれていると言って差し支えないでしょう。
また、身も蓋も無いことを言ってしまえば、あなたの書くコードも私の書くコードも、そんなに見られることなんてないと思います。そりゃあ前述のように就職活動とかで提出したりすれば見られはしますが、そうでなければよっぽど人気が出たりしない限りは誰にも見られません。ただし、 AWS_ACCESS_KEY_ID
などのお金になりそう、もしくはイタズラできそうな秘匿情報が書かれていそうな場合はめちゃくちゃ(Botに)見られます1。 それは気をつけましょう。
公開したからといって、保守する義務はありません。例えばMITライセンスの下でコードを公開している場合は、以下のように現状のまま、無保証で提供されることが明記されています。
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND
作者に保守し続ける義務はないので、ほったらかしにしていてもいいのです。僕もめちゃくちゃ放置しています。そして大抵、自分が使うために作ったものを保守しないでいて困るのは自分だったりします。READMEやCIを整備するのは、そうやって放置していて動かなくなったときに自分が直しやすくするためでもあります。Repositoryの体裁を整えるのは結局自分のためなのです。
極論、個々人それぞれの考えがあってコードを公開する、しないを決めること、それについては個人の自由だと思います。
ただ、「コードを公開するが、ライセンスを明記しない」これはやめてほしい2です。なぜでしょうか。なまじ公開されている分自由に使えそうに見えてしまいますが、ライセンスが不明瞭なため、使用することが一切できないからです。例えばGitHubの場合だと、利用規約上は閲覧することができますが、それ以上のことはできません。これについては以下の記事によくまとまっています。
基本的に、コードを公開するのであれば、例えばSPDXで “FSF Free/Libre” であるか、"OSI Approved" であるか、もしくはその両方なライセンスを付けていてほしい3と思っています。そうでなければ、あなたがどんなに素晴らしいライブラリを作っていようと、そのコードは誰にも利用できないものになってしまいます。OSI Approvedなライセンスで公開されていれば、安心して自分達のアプリケーションでも利用できるかどうか判断することができます。特に業務で使用するのであれば、ライセンスまわりはしっかりチェックする必要があるので、どのようなライセンスの下で公開されているかというのは非常に重要な情報となります。
リポジトリにライセンスを設定することは、GitHubであればWeb上からでも簡単にできます。
結局、私がコードを基本的に公開するようにしているのは、自分にとってメリットがあるからそうしているだけだったりします。結果として他者にとっても嬉しいことがあったりしますが、基本的にそういうのはレアケースです。
puhitakuが注力している電子辞書(Linux及びWindows CE)のハックという領域において、過去に作成されたクローズドなソフトウェアがバイナリでしか手に入らないという状況がつらいというのは非常によくわかります。そういう立場から書かれたあの記事は、いわば「利用者」からの視点が多かったのではないでしょうか。なので僕は、ソフトウェアを公開する「作成者」側の立場でちょっと書いてみました。とはいっても「作成者」の立場でも僕よりpuhitakuのほうが広く使われるソフトウェアを公開していそうではありますが、それはそれ。
GitHub に AWS キーペアを上げると抜かれるってほんと???試してみよー! - Qiita このような秘匿情報は、そもそも環境変数経由で取得するようにするべきです。 ↩
もし僕の公開しているrepositoryでライセンスが設定されてないものがあって困っていたら連絡してください ↩
強い言葉を使うなら、「何らかのライセンスを付けるべきである」と考えます。例えそれがNYSLなどのOSI Approvedでない独自ライセンスであったとしても、です。 ↩
このシリーズも、もう3年目になります。
例によって冒頭の画像はwakatimeによる2021年1月1日から12月16日までのプログラミング言語使用率です。3位はYAML、4位はOtherとのことです。
フリーランスで、主にRailsやAWSを使用しているサービスの運用、開発に関わっています。いくつもの会社を見てきた訳ではなく、数社に深く関わっている都合上、視野が狭いかもしれません。(昨年同様)
今年は仕事の成果として公表できるものはありませんでした。
昨年とは違い、純粋に使用した記憶があるもの、印象に残っているものをリストアップしています。
昨年と比較すると少し減りましたかね。
今年もRubyとRailsで仕事をし、収入を得ることができました。やっぱりなんだかんだRailsはいいですね。今年は新規サービスの立ち上げに関わったのですが、良くも悪くも自分が一番手が早く動くのがRubyでありRailsなので、最速で顧客に価値を提供するにはこの選択になってしまいます。このポジションの道具としてNext.jsを加えられるともっと入れる現場が増えたりするんじゃないかとは思いますが、とりあえず来年もRubyとRailsで頑張っていけそうです。
今年2番目に書いた言語がTypeScriptとなっていますが、実質Next.jsでした。これに関してはKaigi on Rails 2022の運営記として書いたブログにあるように、Firebaseを活用したWepアプリを作ったのがそれです。
まだまだこの分野においては経験値が不足しているのを実感しており、具体的にはRDBとの通信やかっちりとしたバリデーションが必要な性質のものは書いたことがありません。ViewをReactで書き、API部分をRailsで書く、という構成から自分が抜け出せていないのを感じています。サーバーサイドもJavaScriptで書くという技術投資にプライベートの時間を割くのは今年はできませんでしたし、来年も厳しそうです。
言わずもがな、まさに現時点で2022年のRuby Association Grantに採択されたということもあって、QUICのRuby実装を進めているところです。今はただaioquicの移植をしている段階であり、それでも予想はできていましたが大変です。がんばります。
「OpenSSLをがんばる」とは何だという話ですが、QUICをやっていくと必然的にTLSをやっていくことになり、そして必然的にOpenSSLのAPIに触れる必要が出てきます。ところがもちろん、OpenSSLの内部APIに関する初心者向けのドキュメントなんてあるはずがないので苦労するわけです。
暗号技術の専門家を目指して頑張る、ということではなく、OpenSSLの内部APIがどうなっているのか、どう使っていくのが正しいのか、生のCで書かれた処理フローをRubyのOpenSSL gemを使う形式に書き下すにはどうするか、公式ドキュメントの読み方などの方向感覚を付ける、などというのを頑張りたいです。というかできないと厳しい……
現在、QUICの実装に関連してC拡張を含むruby gemを作成しなければいけない状況にあります。なのでC言語を書く必要があるのですが、現在は(もし使用できるのであれば)C言語の代替としてRustやZigを採用したほうがより良いでしょう。
ひとまず既存の資料も多いことから一旦C言語で実装するつもりでいますが、ゆくゆくはRustもしくはZigによる書き換えをしたいと目論んでおり、そのためにもRustとZigはキャッチアップ、比較検討したいところです。そして、それ以前にC言語を書くのが学生以来なので、C言語の基礎的な部分も学び直しです。
今年こそはProposalを出したい……!Grantの最終報告が終われば時間ができるはずなのでそのタイミングで概念実装を、と言いたいところですがRubyKaigiもありますね。どうなるんでしょう。
そしてそれとは別にin-personとonlineでのハイブリッド開催となっており、スタッフ業としても準備するもの、やることが結構あるはずで、しかしまだ全体像が見えていない状況にあります。直前になってバタバタしないように気を張っておきたいところです。
これは昨年やると言ったもののあまりできていないことです。まずできることとして、Grantのreportは英語で書いてみようか……と考えてはいますが、果たして。
あと海外カンファレンスにProposalを出せたらいいなとか考えていますが、果たして。
私はKaigi on Railsのオーガナイザーのひとりです。Kaigi on Rails 2023は物理会場にて開催されることが公開されました。そうなるともちろん、会場でのインターネットについてはどうなる、どうする、という問題が出てきます。それに備えて、先輩イベントであるRubyKaigiを参考にしようというわけで、自分の理解のために書くことにしました。
私はRubyKaigi 2022のネットワークをお手伝いしましたが、ケーブルの巻き直し、APの設営、撤収時の諸々を手伝ったのみです。よってこれから言及する内容については、一般参加者に毛が生えた程度の事前知識しかありません。
またこれから読み解くコードにおいて、コメントする内容の正確性は一切ないものと思って読んでください。
RubyKaigiのネットワークにおけるL3(OSI参照モデルで言うネットワーク層以上)より上の構成(多分)については、このリポジトリで公開されています。
何とは言わんが現場絶賛公開中なんだよな、宿題を放置した自分が全部悪いといいながらやってます https://t.co/J6SoHxBd4P https://t.co/GcPJLU69Rn
— そらは (@sora_h) September 3, 2022
今回は、2022年の会場ネットワークの構築が始まったあたりからのcommitを順を追う形で読み解いていきます。
今回のネットワークの準備はここから開始したと見られます。これ以前にもcommitsはあるのですが、それらは2019年以前のものをimportしたもののようなので、今年には関係ないとして無視します。 実際、このcommitでもitamaeのrecipeを削除してscratchからやりなおす、という意図を感じられます。
subnetを3つ、route_tableをひとつ定義しています
AWS Direct Connect ゲートウェイを定義しています。AWS Direct Connectとは……
AWS Direct Connect は、お客様の内部ネットワークを AWS Direct Connect ロケーションに、標準のイーサネット光ファイバケーブルを介して接続するサービスです。 https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/Welcome.html
とのことです。(今知った)
Route 53に rubykaigi.net
のZoneを定義しています。ネットワーク関係の色々は *.rubykaigi.net
で提供されました。
踏み台インスタンスを定義しています。関連するIAM roleであったり、SSH loginできるユーザーの公開鍵の設定などもあります。
DNSの逆引きを設定しているんだと思います。この記載で 10.0.0.0
になるってこと……?
https://manual.iij.jp/dpf/help/19004700.html
これは単純にTerraformのdirectory構成の変更ですね。
様々な機器のDatacenter、Network、CIDR、IP等を定義したhosts.txtを作成(というより更新)し、その内容から aws_route53_record
を作成するRuby scriptを経由してRoute 53にTerraformからrecordを登録するようにしています。まあこれは手では書いていられないですね……最終的なhosts.tfは1400行弱になっています。
Roadworkerを削除しています。RoadworkerはRubyによるRoute 53をDSLによって管理できるgemです。Terraformによる管理に乗り換えたから、ということなんでしょう。
awsroute53record 大量に発生すると一瞬で terraform apply 遅すぎてやってられん状態になるし roadworker はなんだかんだ捨てられないなぁ
— そらは (@sora_h) August 22, 2022
NAT Gatewayが有効になりました。
EKSによるKubernetes clusterが爆誕しました。というか、Cookpad org以下にterraform moduleが公開されているんですね。
https://github.com/cookpad/terraform-aws-eks
注目すべきは、このクラスタは全部ARM instanceで稼動するような設定になっているところです。
VPN間でのrouteのpropagationを設定しています。
K8s clusterに属するnodeの設定です。
https://github.com/aws/aws-node-termination-handler をHelm経由でdeployしています。こんなのがあるんですね。
AWS Load Balancer Controllerをclusterにdeployしています。
AWS Load Balancer Controller アドオンのインストール - Amazon EKS
証明書とALBを作成して *.rubykaigi.net
ないくつかのhostを定義しています。こんなの生えてたのか。
dexをdeployしています。dexというのは https://dexidp.io/ です。 これで何をしたいかというと、 *.rubykaigi.net
でhostされているいくつかのresources(例えば grafana.rubykaigi.net
)へのアクセス権限を絞るためです。今回はGitHubの特定teamに所属しているメンバーに対しての許可を与えるような設定が書かれています。
また主にこのcommit以降からだと思いますが、K8sで使用するYAMLをJsonnetから生成するようになっています。
で、そのテスト用のendpointを作成しています。ちゃんとAuthrorizeされていれば画像が見れるはず、というやつ。
wgbridgerを導入しています。wgbridgerというのは、
build L2 bridge using Wireguard to bring NGN to behind IPv4 NAPT only environment…
というもの(?) これはあれかな、準備作業中に見せてくれた、どこでもNGNに繋がる便利Raspberry Piの実体かな?
dexをOIDC準拠IdPとして使用した認証を利用し、AWS Management Consoleへのアクセス権限を特定のIAM Roleによって行えるような機構、AMCを用意しています。つまりどういうことかというと、あるGitHub teamに所属している場合、その認証情報を用いてAWSのConsoleに入れる仕組みです。 tf/amc/src/app.rb
がキモだと思うんですが、難しいよぉ……
AMCのREADMEに追記が行われています。
AMCに関連する処理のなかで、curlによる証明書チェーンが正当かどうかの検証を追加しています。
ここからKeaのための準備が始まります。Keaが何者かというと、DHCP serverです。このcommitでは、Docker imageのbuildやKeaを起動するためのscriptなどの準備をしています。
これはKeaのためのAuroraを準備しています。
JsonnetをYAMLにするscript内部で、生成したファイルの扱いがちょっと変更されています。rsyncにしたのは更新日時とかそのあたりの都合?
Keaが運用され始めました。
Keaに対するhealthcheck用のendpointを用意しています、Rustで。Healthcheckそうやってやるんだ……なるほど……?
NocAdmin roleに対してロードバランサーへの権限を解放しています。
Kea関連のdeploymentで参照しているcommit hashを更新しています。
NocAdmin roleに対してRDSへの権限を解放しています。
これはちょっとわからない……NocAdminBaseとNocAdminに権限を分離して、権限昇格を防いでいるんだと思いますが多分。
権限の昇格を防ぎ、アクセス許可の境界で IAM ユーザー範囲を限定する
🍝
NocAdminに対して許可するiamへの権限をいっぱい追加しています。
687e37bで導入されたterraform moduleをfork先のものからfork元のものを使うよう修正しています。ARM対応がmergeされたのがこのタイミングだったのかな。
Terraformのexternal data sourceとして、Jsonnetを指定してJSONを吐くときに使うためのRuby scriptを定義しています。
このあたりからPrometheusの設定が始まります。ここではALBのための設定を作成しています。これらのendpointもdexを経由して認証されるようにしていますね。
Helm経由でPrometheusをK8s clusterにdeployしています。
blackbox exporter を用意しています。ICMP (ping)でどこかを監視する用かな。
8.8.8.8
に対して60秒ごとにICMPを投げるように設定しています。これはインターネットへの疎通確認かな?
Prometheusのdata retensionを1分から30日に変更しています。
clusterへの設定を他のtfから参照できるようにoutputしています。
ハードコードしていた設定値を、先ほどoutputしたclusterの設定を用いた形に書き換えています。
hosts.txtが更新されました
snmp-exporterを設定しています。SNMPはSimple Network Management Protocolのこと。CiscoのWireless LAN ControllerやNECのIX Routerの監視に用いていたのかな。
先のcommitで作成した設定値をprometheus側に反映されるようにK8sのmanifestを設定している、という理解でいいのかな
Grafanaです。
Keaの監視もPrometheusで行うようになりました
wgbridgerのためにMTU値を上げています
Wireless LAN Controllerにアクセスできるようになりました。
PrometheusからのアラートがSlackに送られるようにしています。
Jsonnetに対してformatterをかけています。
Prometheusがmetricsをscrapeする間隔を60秒から20秒に変更しています。
clusterでのOIDC configを別tfから参照できるようにexportしています
NocAdmin roleに対してDynamoDBに関する権限を解放しています。なんかで使うんでしょう。
なるほど、State lockでDynamoDBを使うためだったんですね。
Backend Type: s3 | Terraform | HashiCorp Developer
NocAdmin roleに対して iam:UpdateAssumeRolePolicy
を許可するよう変更しています。
cloudwatch_exporterを有効にしています。AWSのresourceもPrometheusでモニタリングするためでしょうね
hosts.txtを更新しています。IPv6の指定が増えてますね。
さらにhosts.txtの更新。もりっとhostが追加されています。
hosts.txtからtfに変換するscriptを修正しています。IPv6の取り扱いとかに修正が入ってますね。
typo
これは……なんだろう、多分何かの機器用の設定を生成するためのscript。NECのルーターだと思うけど。
Syslogを置くためのS3 bucketへの権限をNocAdmin roleに付けています
Syslog関連のterraformのための場所を作っています。
Syslogのためのfluentdを置くECR repositopryを定義しています
Syslogのためのfluentd containerを作成しています。GitHub Actionsでdocker buildをしていますね。
git submoduleのrepository URLをssh形式からhttps形式に変更しています。鍵がない環境でcloneできないから、でしたっけ。たぶんGitHub Actionsで不都合になったのか……?
fluentd pluginを作成しています。これはまずhealthcheckだけやってる感じ?
GitHub ActionsからECRにpushできるような権限を付与しています
Syslog用のIAM role、K8sのservice accountを作成しています。EKSでIAM roleとの連携ってこうやってやるんだ。
fluentdの設定、k8sのdeployment諸々が作成されています。これでEKS clusterにfluentd containerが稼動し始めたのかな。
SyslogのためのSecurity groupを作成しています。fluentdに向かう通信を許可しているはず。
fluentdのhealthcheckのために、pluginを作ってやっていたものからmonitor_agentを使う方式に変更しています。
https://docs.fluentd.org/input/monitor_agent
GitHub Actions内で参照していたpathの修正です
S3に置くlog fileにhostnameを付与するようにしています
fluentdが終了するときにbuffer(?)をflushするようにしています。これないと書き出し切らずに終了してしまう?
tagでchunkが分離されてしまうのを防いでいる?
terraformでbastion instanceに対してはAMIの変更を無視するようにしています。
use static NAT on onpremises router devices so they don’t need to handle dynamic NAPT table and allow redundancy
「オンプレミスのルーターデバイスで静的NATを使用することにより、動的NAPTテーブルを処理する必要がなく、冗長性を確保できる。」 あ~はいはいなるほど完全に理解した
unboundがアップを始めている
unboundをCache DNS serverとして運用するみたいで、そのためのECRとsecurity groupを定義しています。
独自のunbound exporterによる監視を有効にしたunboundのcontainerをbuildしています。Jsonnet大活躍。
フィックスタイポ
unboundの設定です。
特定の逆引きに対しては特定のIPに送るようにしてい……る?このIPがVPC resolverを指している?
deployされるunboundを更新しています。
68c205fで設定したlocal-zoneに対してnodefaultを付けています。unboundなにもわからない。
nodefault AS112ゾーン(※)のデフォルトの設定をオフにする ※ AS112ゾーンはプライベートアドレスやリンクローカルアドレスの逆引きのゾーンのことです。Unboundではデフォルトでこのゾーンに対する問い合わせにはNXDOMAIN(情報なし)を返します。 第4回 Unboundサーバ運用Tips | gihyo.jp
NXDOMAIN
を返さないようにした、ということなんでしょうか。
unboundの設定を変更して性能を調整しています。
unboundが unbound
userで動作するようにしています。
グオオオ
venue下のsubnetに対してKaeで払い出すIP rangeを指定している……でいいのか?
unbound containerに対してTCPでも通信できるようにしています。heathcheckとかでも使うから。
https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/deploy/pod_readiness_gate/
なる、ほど、ね……?
😜
NLBのsubnetからunboundへのhealthcheck accessをできないようにしています。metricも同じportで提供するから、というのはmetricに影響が出る?
これはterraformのfor loopの設定。
./gen-workflows.rbを実行した結果をcommitしたんだと思います。
Availability Zoneごとに配置されるよう、nodeのmin_sizeを2にしています
hosts.txtが更新されました。tmpに対して名前が付きましたね。
unboundに対するPrometheusからの監視を設定しています。internalなhostnameとexternalなhostnameに対する名前解決もするようにしていそう。
unboundに対してtopologySpreadConstraintsを設定しています。Zoneごとにちゃんとばらけてくれるようにしています。
KeaがDNS resolverとして使うものを 8.8.8.8
からunboundに変更しています。
IP addr足りなかった?
PrometheusがSNMPで監視する対象のhostを増やしています。
CiscoのWLCに対してSNMPで取得するmetricを追加しています。
5788b2eで指定したWLCのhostnameを修正しています
これちょっとよくわからない……WLCの居場所に関する設定?
ダメらしい。 f52e1bc で追加した一部の設定をコメントアウトしています。
hosts.txtを更新しています。順番が上に移動しただけ?
さて、会場でRubyKaigiのライブ配信を見ようとした場合には見られなくなっていたと思いますが、これがそれです。特定のS3 bucketに対し、会場内ネットワークからのアクセスであればDenyするような設定をしています。
ライプ配信視聴アプリ側ではここでその制御を行っています。
AWS Direct Connectのmetricもcloudwatch-exporterで収集するようにしています。
AWS Elemental MediaLiveのmetricもcloudwatch-exporterで収集するようにしています。
RubyKaigiのライブ配信がどのようにAWSのサービスを使用して実現されているかはこの記事に詳しいです。まあ作者が書いてるので……
プリンター?
一時的に val-permissive-mode: yes
にしています。これなに?
DNSSECを無効にする方法 – 日本Unboundユーザー会
なるほどね。
先の変更を削除し、zoneの逆引きの設定を変更しています。
privateなzoneは信頼するように設定しています……というかDNS周りのこれらの設定を日本語に起こすときの言葉の選択が正しいのか全然自信がない。
private IPのみ逆引きをforwardするよう変更しています。
EC2やEBSなどへの監視設定をPrometheusに対して行っています。
sorah/cnwからPrometheusの設定を拝借しています。
ここからは設営日 (9/9)になります。
SNMPで監視する対象がDOWNしている場合のアラートを設定しています。
NECのルーターに対してのアラートを設定しています。CPU使用率かな?
WLCに対してSNMPで取得する項目を追加しています。
プリンターの居場所(というよりはhosts.txtから生成される定義?)が間違っていたっぽく、それを修正しています。
今思い出したけど、これテプラのラベルプリンター?
SNMPで監視している対象の機器が再起動したときのアラートを設定しています。
NocAdmin roleに対してtakeout-app(配信視聴アプリ)関連のS3 bucketへの権限を付与しています。
自分が会場ネットワークにいるかどうかの判定に使用するBucketのresponse cacheが長いので1時間に変更しています。
いかがでしたか?
Kaigi on Rails 2022に参加していただいた皆様、ありがとうございました。登壇者の皆様、Proposalを出してくださった皆様、協賛してくださった企業の皆様、そして一般参加者の皆様のおかげで、Kaigi on Railsは今年も開催することができました。
Kaigi on Railsが継続的に開催されるためには、もちろん登壇したいとProposalを出してくれる方々、協賛して下さる企業の方々の存在も欠かせませんが、参加者の方々の感想も非常に重要です。楽しかった、学びになったなどのご感想は非常に嬉しいですし、ここはもっとこうだとよかった、などのご意見も、次回開催をより良いものにしていくためにはとても重要なものです。
では今回も雑用1&動画&配信周りを担当した僕からつらつらと振り返った感想を書いていきます。忘れないよう準備期間から書いていることもあり、項目間に繋がりがないですが、そういうものと思って読んでください。
自分も日々Railsアプリを開発することを生業とするプログラマーの1人なので、もちろんProposalを出したいという気持ちもあり、あたためているネタもありました。また業務委託として関わっている会社においても、Proposalを書く会に参加したり、Slackで迷っている人の背中を押したりしていました。
そんな中、Proposalを書き進めていくうちに、これに本当に価値があるのか?という疑問が浮かんでしまい、とうとう提出できないまま締め切りを迎えてしまいました。Proposalを出してもらう側としては、「価値があるかどうかはこちらが決めるからとにかく出してほしい!」と言う側だっただけに、自分自身がこういう結果になってしまうのは本当にいかがなものかと思います。
あとは実際に開催準備を進めていくなかで、この作業量で登壇するのは無理があったなということもわかりました。ふーがさんはすごい。
昨年のreBakoの体験が良すぎたので、今年もそのようなものを期待されていた会社さんも多かったのではと思います。しかし裏側の準備が実はとても大変でした。昨年の大倉さんによるレポートでもそのことが伺い知れるかと思います。端的に言ってしまえば、業務として取り組むレベルで作業時間が確保できるのであれば完成度の高い「場」が作れるが、我々はそうではなかった(昨年は無茶をした)ということです。それらの反省を踏まえ、今年はSpatialChatにブースを置くということになりました。スタッフが増えたこともあり、ブース設営に関しては昨年と比較して非常に健全な労力で行われたと感じています(ブースの準備には僕は参加できていませんが、準備期間のSlackの流量が全然違う)。
僕は配信を担当していたということもあり、SpatialChatのほうには顔を出せませんでしたが、他スタッフからの様子の報告であったり、TLを流れていくスポンサー各社様の催しの告知や感想を見ている様子では、reBakoじゃないとやっぱり厳しいかなという気持ちは取り越し苦労だったのかな?と感じました。それぞれのツールにはそれぞれの利点もあり、それぞれのつらみもあるものですが、今年のブースも皆さんに楽しんでいただけたようで何よりです。
Kaigi on Rails 2022では録画での発表をサポートしています。これまでは、発表内容を録画した動画を提出してもらうのに、Google Formを使っていました。これは手軽な反面、Google Driveの容量を消費してしまいます。現にKaigi on RailsのGoogle Driveの使用率は80%に達しており、何か別の方法を考えたいところでした。もちろん保存容量は購入すれば済む話ではありますが……
そこで、ファイルをアップロードしてもらい、Firebase Storageに保存する2ための簡単なSPAをNext.jsで作成しました3。これはFirebase Authenticationのメールリンク認証によってログインすることでアカウント作成の手間を削減するなど、なるべく簡便に使えるように設計しました。Firebaseって便利だな〜〜というのが実感できました。ただ、アップロードできないケースが1例だけあり、それは申し訳ないと思っています。
同様のものはもちろんActive Storageを使用したRailsアプリでも実現することができます。しかし数ヶ月の使用期間しかないものに対してサーバー(herokuで言うところのDyno)を維持するのもなんだか、ということもあり、Next.jsとFirebase Hostingを選択しました。結果は37GBほどの動画ファイルを受け付け、諸々にかかった費用は2000円弱となりました。
今年も昨年同様、提出していただいた登壇動画のレイアウトはめこみや音量などの調整、基調講演の字幕付けを行いました。ここについては特筆することはなく、単純に手を動かすだけ4でした。一番時間を取られる割に特別なことはしていないので、特に書くことがありません。
今年もKaigi on Railsは、ZoomとOBSとYouTubeを組み合わせた配信によって開催しました。ライブでの登壇者にはZoomの部屋に入ってもらい、そこから映像をOBSに流しこんで画作りを行い、YouTubeへ配信する、という構成です。具体的には2020年に書いたKaigi on Rails STAY HOME Edition 配信の裏側に書いたような構成です。
さて、2020年及び2021年は、ZoomのデスクトップアプリとChromeから参加しているZoomの画面を、それぞれ登壇者の共有している画面、登壇者のカメラ映像に割り当て、それぞれの映像をOBSでウィンドウキャプチャしたものを配信レイアウトに流し込んでいました。この方法の欠点は、Zoom側の操作で画面のレイアウトが変化するとレイアウトが崩壊する、画面の切り抜きの領域を細かく調節する必要がある、など、要は登壇者の切り替わりのタイミングの数十秒で細心の注意を払い、なおかつ素早くレイアウト調整を行う必要があるということです。
そこで今回は、NDIを使用するためにZoom Roomsを導入しました。Zoom Roomsでは、NDIによる映像出力が可能です。
Using Network Device Interface (NDI) – Zoom Support
この機能を用いて、まず完全に独立したWindows機5でZooom Roomsをホストします。そのZoom Roomsに入ってもらっている登壇者の共有している画面(発表スライド)、登壇者のカメラ映像のそれぞれを個別にNDIによって出力し、OBS側ではそれらをobs-ndiを用いて受けとることで、安定したレイアウトによる配信を実現できました。この構成は、RubyKaigi Takeoutを参考にしています。
また、配信担当メンバーである僕のメインPCが最近謎のブルースクリーンで再起動をする6という現象がそこそこ発生しており、これが配信中に発生するとしんどいという問題がありました。そこで、OBSからの配信については、Google Cloud上にGPUを追加したインスタンスを起動し、そこから行うようにしました。Google Cloud上のインスタンスへの映像送出については、NDI Bridgeを使用しました。
具体的な配信の構成はこのようになりました。
検証を始めるタイミングが少し遅かったせいで、結局僕の家のZoom Roomsが単一障害点となってしまう問題は発生してしまいまいたが、配信中の細かい共有範囲の調整などのトータルの労力は昨年よりは減ったのではないかな、と感じています。
NDIを使用したイベントの配信に関する詳細については、以下の記事が参考になるかと思います。僕も参考にさせていただきました。
Zoom以外の選択肢として、ここ最近、様々な企業が開催する配信イベントでStreamYardが使われているのを観測しています。Kaigi on RailsでもStreamYardは試してみており、とても使いやすいと感じました。しかしStreamYardでは、Kaigi on Railsでやりたい「スポンサー企業のロゴをループでずっと流し続ける」ということができませんでした7。
これはイベント自体の運営には必須でない、趣味の領域でやったことについてです。(イベント運営自体そもそも趣味の領域なのかもしれませんが)
昨年の配信において、場面転換のところでアニメーションがかかっていたのを覚えていらっしゃるでしょうか。あれは配信班のメンバー、yrindaさんが突然持ってきたもので、僕含めスタッフ一同すごい!となったものです。
今年は、あれから僕も高専DJ部で映像を出すためにAfter Effectsを触るなどして少しわかってきたので、トランジション動画を作ってみることにしました。できたのが以下の2つです。
こういうものは、ツールの使い方を習得するのはもちろんですが、そもそもどういう映像を作ろうか、というアイデアを思い付くのも大変でした。一時期は寝る前に布団に入った後、ずっと頭の中で動画の構成を考えていたほどです。
熱が冷めないうちに書いておきます。この3年間、決して少なくない時間を割いて、このKaigi on Railsというイベントの運営に関わってきました。僕がなぜそこまでするのか。それは以前「Railsを主戦場としている自分が今後学ぶべき技術について(随筆)」 にて、
学生時代にRubyを触ったのが始まりとなって新卒でRailsを書き始め、そこからキャリアの大部分にRubyとRailsがしっかりと喰らい付いている自分は、Rubyに対してもRailsに対しても結構愛着がある。レガシーとなってほしくはない。採用され続ける選択肢であってほしい。
と書いたように、Railsという技術に対しての愛着や、その周辺に存在するコミュニティへの感謝があるからです。そしてそれだけではなく、Kaigi on Railsが、そのコンセプトとして掲げている、
また、名前の通りRailsを話題の中心に据えるカンファレンスではありますが、広くWebに関すること全般(例えばフロントエンドやプロトコルなど)についてもカバーすることで参加者の知見を深め、また明日からの仕事に役立てていただければと考えています。
にもあるように、「広くWebに関すること全般」を扱うカンファレンスでもあるからです。Railsはもちろん好きですが、それに留まらないWeb技術を広く扱うことのできるカンファレンスというものを続けていきたいのです。例を挙げるならば、2020年のsylph01さんによる、メールに関する各種概念の解説があったセッション「Action Mailbox in Action」や、2021年のohbaryeさんによる、IETF draftとして提出されているIdempotency-Key Headerに関するセッション「Safe Retry with Idempotency-Key Header」や、今年のursmさんによる、ギガバイトクラスの大規模なファイルを扱うためにWeb Workerを駆使したセッション「大量塩基配列登録申請システムができるまで」などです。 RubyKaigiがRubyの話に留まらず、C言語やコンピューターサイエンスの最先端の話題を扱うように、Kaigi on Railsも、Railsというフレームワークに縛られない、Webの最先端の技術であったり、組織論についての話題であったりを受け入れる裾野の広いカンファレンスであっていたい、そんな話題を聞きたい、そのためにオーガナイザーとして今後も関わっていくつもりです。
また、カンファレンスを運営する立場になると、「好きなことができる」というのは、少なくない時間を投入する立場としては嬉しい点でもあります。例を挙げるなら、前述のファイルアップローダーは完成したものをいきなりスタッフ間に公開して「今年はこれを使うぞ!!」ということをしましたし、NDI経由での映像をGCP上のWindows Serverで受けとりそこから配信する、といったチャレンジも僕がやりたい!と言ったからできたものです。
もちろん自分の言い出したことで失敗しないように検証に検証を重ねることは必要ですし、そこで費用が発生するのであれば申請が必要だったりと手間はかかりますが、やはりカンファレンスを内側から好きなように運営できるというのは非常に楽しいことです。
来年もKaigi on Railsは開催される予定です。そしてクロージングでも言及があったように、ようやくリアルに会場を押さえたin-person形式での開催ができそうです(記事公開時点で未確定)。リアル会場での開催となると、今までのようなリモートでの開催とは比にならないほど考えることが増えるでしょう。そういう意味でもスタッフはより増えてほしいですし、お手伝いはしたいが、そんなに時間を割くことはできないという方でも、当日スタッフという形での協力もできるのではないかと思います。
来年も皆さんの、様々なかたちでのご協力をお待ちしております。
cfp-app, sponsor-appの運用、ドメイン設定、議事録など ↩
アイデア自体は sorah/s3-collect からです。ただしKaigi on Railsは後述するように、主にGoogle Cloudを使用しているので、独自の仕組みを作成することにしました。つくりたかったという気持ちもあります。 ↩
実は去年から運用に乗せたい気持ちがあったのですが、自分がNext.jsにもFirebaseにもあまり慣れてないので実装に時間がかかり、今年からの運用になってしまいました。それでも最後のほうは募集開始に間に合わせるために勢いで書き上げたので結構汚ないコードになっており、JavaScriptが得意な人に個人的にお金を払ってもいいからレビューしてほしい気持ちがあります。個人的に、ですよ? ↩
なんだかんだで1日目の夜になっても動画編集をやっていたことについては改善の余地があると思っています。僕の初動が遅かった。 ↩
家に余っているマシンを初期化してこれに割り当てる予定でしたが、色々あってなぜかPCが1台増えました。どうしてこんなことに? ↩
イベントビューアーを見ても原因がわからず、対処のしようがない! ↩
少なくとも僕が検証した時にはできませんでした。もしできるのであれば教えてください。特定企業が運営するのであればこの要件は不要なので、手軽に配信イベントを開催できるいい時代だと思います。 ↩
https://slide.rabbit-shocker.org/authors/unasuke/rubykaigi-2022/ (みんなRabbit使おう!)
昨年の発表から方針を変更し、実装をしていく中で、Rubyだとつらいな~と感じた事について話しました。発表内で、「Ractorをやめた」という表現をしましたが、実際にはRactorに依存しない部分もそれなにり書き直しており、そのためコードの外部から見た振る舞いは、昨年からは微々たる進展しかありませんでした。
発表後、バイナリデータをRubyでそのまま扱うことについて、Samuel氏から IO::Buffer
の存在について教えていただきました。
@yu_suke1994 have you looked at IO::Buffer?
— Samuel Williams (@ioquatix) September 9, 2022
これはバイナリを扱うことについては既存のString、Integerよりも適していそうではあるものの、その内容に対して演算したい場合にまだまだ機能が不足しているのではないかと感じました。また、発表で用いたString、Integerでの操作を行うベンチマークを IO::Buffer
も対象にして実行してみたところ、3つの中では最も遅いという結果になりました。
https://github.com/unasuke/rubykaigi-2022/commit/1e4470d55217d6c8 (これ、experimentalの警告を消す段階で hello_world_upcase_io_buffer
のWarming up、Calculatingの結果が消えていますね……ミスです……)
この結果についても会場でSamuel氏と話したところ、演算する過程で都合上 set_value
と get_value
をしている部分があるのですが、そこでオブジェクトの正当性のチェック処理が走っている1のが原因ではないか、ということを教えていただきました。
ところで、言ってしまえば前回のRubyKaigiからこれまでの間に、もっと多くのコードが書けたはずでした。しかし、昨年の発表の直後に開催されたKaigi on Rails 2021の運営、さらにその後に控えていたCloudNative Days Tokyo 2021での発表と、立て続けにイベントがあったことで若干燃え尽きてしまいました。しばらくプライベートの時間でQUIC関連のコードを書く気持ちになれない期間が続いていました。そもそも趣味プロジェクトだし、差し迫った締め切りというものも存在しないのも大きな要因でしょう。
なので今後は、もうちょっと自分を追い込んでいこうかなと思っています2。具体的には、Rubyアソシエーション開発助成金2022に応募しました3。50万円という助成金よりは、成果発表をしなければいけないことによって強制的に手を動かす動機ができること、もしかしたらメンターが付くかもしれないということのほうが、今の僕には魅力に感じました。採択されなかった場合も、別の形で締切を生み出す案がうっすらとあるので、ともかくやっていこうと思います。
そして、実は今回のRubyKaigi 2022において、会場のインターネット設営の準備をお手伝いしていました4。
荷物整理終わった #rubykaigiNOC #rubykaigi pic.twitter.com/j1noLwgUHM
— そらは (@sora_h) September 11, 2022
2018年、2019年とhelperとしてやっていたのが一旦なくなったことで、3年ぶりにケーブルを8の字巻きしたり、ケーブルを這わせに会場を駆け回ったりするのはとても懐かしかったです。 そういう訳で、一般参加者T、登壇者T、スタッフTの三種5を手にすることができました。in-personの嬉しいところは、ちゃんとそれぞれの属性に応じたTシャツを手に入れられることにもあると感じました。
本編終了後には、ピクシブさんの主催するアフターパーティーでDJをさせていただけました。これがめちゃくちゃ楽しかったです。
ちなみにこれを聞いたのがこのタイミングだったのですが、クラブイベントの参加も初めてだったようで、それも楽しかったとおっしゃっていただけたのもとても嬉しかったです。
「初めてでしたけど楽しかったです!」って言ってもらえてめっっちゃ嬉しかったよね #rubykaigi
— うなすけ (@yu_suke1994) September 10, 2022
来年のRubyKaigiは松本リベンジということですが、実は7月になぜか松本に行っていました。このときは車で行ったので、来年も車で行こうかな?と思ったりしています。
— うなすけ (@yu_suke1994) July 1, 2022
でも実はそれより先にKaigi on Railsがあるので、まずはそれに向けてがんばっていきます。
これは自分用備忘録です。
/Library/Input Methods/AquaSKK.app/Contents/Resource/kana-rule.conf
を ~/Library/Application Support/AquaSKK/kana-rule.conf
にコピーする~/Library/Application Support/AquaSKK/kana-rule.conf
の末尾に以下を追記する (EUC-JPである1ことに注意)!,!,!,!
?,?,?,?
元記事で書かれている ~/Library/AquaSKK/kana-rule-list
とは何で、現在はどうなっているのでしょうか。調べてみました。
※ 以下記述はインターネット上の記述から僕が理解した内容で、憶測を含むため間違いが含まれている可能性が大です。当時を知っていて間違いに気付いた方は正しい歴史を教えてください……
まず当初、AquaSKKはText Services Manager2を利用したソフトウェアで、この時点での設定ファイルは ~/Library/AquaSKK
に置く3ようになっていました。
後にMac OS X 10.5 (Leopard)で導入されたInputMethodKit4 (以下IMK)を使った実装では、設定ファイルは ~/Library/Application Support/AquaSKK/
に置く5ようになりました。
冒頭で言及した記事が書かれたのは2008年11月12日ですが、AquaSKKのIMK対応が開始されたのが2007年12月15日、IMK対応のコードがSVNリポジトリにコミットされたのが2008年6月26日です。(以下ChangeLogより)
https://ja.osdn.net/projects/aquaskk/scm/svn/blobs/head/aquaskk/trunk/ChangeLog
そして、IMK版対応の中で、2008年8月3日に移行スクリプトが作成され、この内容から ~/Library/AquaSKK/kana-rule-list
に書いていた内容は ~/Library/Application Support/AquaSKK/kana-rule.conf
に書くようになったことが推測できます。
https://ja.osdn.net/projects/aquaskk/scm/svn/commits/15
この移行スクリプトは2015年に削除されました。
https://github.com/codefirst/aquaskk/commit/da2ad5c264e7d9b91c4c9c4e015cb2db8a2a87c5
https://ja.osdn.net/projects/sourceforge/wiki/potm_0811_AquaSKK
kana-rule.conf
の文字コードについて注釈を追加記載する文字種によって保存する文字コードが EUC-JP
以外になる場合があります。 https://twitter.com/tobetchi/status/1722908547045019681 ↩
https://web.archive.org/web/20040407002805/http://developer.apple.com:80/documentation/Carbon/Conceptual/UnderstandTextInput_TSM/index.html ↩
https://moch-lite.hatenadiary.org/entry/20090116/p1 の 「TSM版の設定ファイルは以下にあります。」より ↩
https://moch-lite.hatenadiary.org/entry/20090116/p1 の 「Imk版の設定ファイルは以下になります。」より ↩