第11話 揺れるきつね、決意のきつね

ネタバレ注意


ガーリッシュナンバーユーリ!!! on ICEとが素晴らしかったので、伝統に従って近況報告をします。

※個人の感想です。

退職しました

2014年5月31日を持ちまして、6年ほど在籍したIBM東京基礎研究所を退職しました。

前々から退職エントリを書きたいと思っていたのですが、なんかずるずると書かないままになっていました。
でも、ガーリッシュナンバー(特に11話)とユーリ!!! on ICE(特に5話)を見て、心境に変化がありましたので、今の私についてみなさんにお知らせしたいと思いましたので本エントリを書きました。
ガーリッシュナンバーはいいぞ。ちーさまは超いい子だぞ。目玉焼きトレーナー欲しいぞ。アニメを見てコミックも買うとよいぞ!

そのような文脈(どのような?)でありますので、退職に関する話題はあまりないです。気になる人はTwitterあたりで聞いてください。
非技術的な事由によりあまり居る意味と働く意味が無くなったので辞めた感じです。

無職でした

ここから私は半月の無職期間に突入しました。
その間に無職で学会発表したり、名古屋大学に遊びに行ったりなかなか楽しかったです。
無職はいいぞ!

就職しました

2014年6月16日付けでGoogleに入社し、現在はアメリカでChrome/Blink*1の中身を作っています。
「ブラウザに新機能追加してユーザーさんに喜んでもらうお仕事もいいなぁ」とか軽い気持ち(CV:平沢唯)もあったのですが、気づくとどんどん低レイヤーの地味にお仕事に引き寄せられていく自分を感じています。
主なお仕事としては以下のようなことをしています。

Thread Safety 警察

Blink では String オブジェクトが性能等のためにスレッドセーフでない、などの事由により、スレッド間でデータを受け渡す時に細心の注意を払って String がスレッド間で共有されないようにする必要があります。
それを半自動的に保証する機構として、「スレッド間でタスクを投げる時には、CrossThreadCopier*2WTF::bind()*3を通してタスクを投げる」というお約束があったのですが、2014年段階ではそれに色々な問題がありました。
本当に色々とあったのですが、一例としては

  • そもそもCrossThreadCopierの実装が間違っている
  • WTF::bindの生成する一時オブジェクトのデストラクタのせいでrace conditionが発生する

などなど。雰囲気としては

  postTask(bind(&foo, bar)) // foo(bar) を別スレッドで実行する
  ; // セミコロンしか見えないけど実はここでbind()が返す一時オブジェクトのデストラクタが走って
    // foo(bar)とrace conditionが生じる!

みたいな「知らんがな」案件(完全にbindの設計によるものでbind呼ぶ人は悪くない)。
しかも実際にraceしているのは「この一時オブジェクトのメンバであるshared_ptrの指すオブジェクトのメンバであるunique_ptrの指す型の子クラスのメンバであるunique_ptrの指す型の子クラスのメンバのメンバのメンバであるshared_ptrのデストラクタ」とかいう「知らんがな」案件も発生していた。

「こんな泥沼の上でコードを書いていられるか、全て焼き払ってやる!」みたいな気分になった私は勝手に20%ルールであると称して、関連ライブラリの一部再設計をしていました。
2016年には同じあたりをいじっていた人と合流して Threading Team を立ち上げて一緒にやっていたりしました。
現在はcrossThreadBind()を呼べば割と安全なようになっていて、また型も「別のスレッドに投げていいクロージャ」と「そうでないクロージャ」で別にしたので、将来的に制限をもっと強くできるようになっています。

空白やセミコロンや閉じ中括弧しか見えない場所に何かを見出すスキルが身につきました(ぉ。

設計の沼感を味わいたい方向けにはThread-Safety around bind()というスライドを作ったのでそちらとかをどうぞ。
(ほんとはもっとたくさんDesign Docを書いたのですが、スレッドセーフティはセキュリティ案件と近いこともあってほとんどがprivateなものになっています)

XMLHttpRequest (XHR) / Fetch API などの実装・保守

ネットワークAPIチームという、XHR/Fetch API/WebSocketsなどを担当するチームがあり、そこで主にXHRとFetch APIをいじっていました。
Fetch API のテストとかバックプレッシャーの実装(ほぼ唯一の新機能実装?)とかバグ修正全般とか。
バックプレッシャーの実装は
私「締め切りまで2週間しかないがこれあと3週間はかかります!」
Yさん「よし2人で実装すれば1.5週間で終わるぞ!!」
私「??!!!!!」
みたいな感じでした(実際間に合った)。

Blink側ネットワークコード全般のリファクタリング・保守

ローディングチームという、ネットワークからデータ持ってくること関連のチームの一つにいます。
これも完全に裏方仕事です。

「ここのコードには空白しかないように見えるが実はここでデストラクタが走ってネットワークがcancelされてJavaScriptが実行されてその中でこういうコードを実行すると良くないことが起きる……!」
「ここのコードの設計は良くなくて、Aの中でBを呼んでその中でC呼ぶと秘孔が突けるので再設計しよう」
「AとBとCは本来どのような順番で呼んでも動くべきなのだが不運な偶然によりA→B→Cの順番で呼ばないと動かない、しかしこれは新機能実装を阻害しているので順序依存性を解消しよう」
みたいなことを考えていて、大変地味です。
しかし一発ミスるとセキュリティホールが開いたりするので緊張感のある重要なお仕事でもあります。

何やっているのかよく分かりませんか? 私にもよく分かりません。
「何かがおかしい(けど重要性がよく分からない)、これ現実逃避で遊んでるだけじゃないのかなぁ」みたいなことを積み重ねていくと、ある日「二週間前のアレと三ヶ月前のアレと半年前のアレ、来月までの新機能実装に必要じゃん!」ということに気づいてやっと「なるほど、やはりあのよく分からない挙動は修正する価値があったのだ! 私は別に現実逃避で遊んでいたわけではなかったのだよ、勝ったなガハハ!」ということになることもあり、本当に基礎工事感があります。

最近では load event (, とかで指定するやつ) の制御に問題があるのでそこを直しています。
onload のタイミングがびみょーにズレて何か壊したら私のせいかもしれません。

感想

現職全般の感想としては

  • 「人間でも開発できる体勢になっている」

前はコンパイラ開発とか人外だけで回すお仕事だったので。ドキュメントがある、単一の神にお伺いを立てなくてもコードが書ける、その他全般的に神不在でもプロジェクトが立ち行くようになっていてすごい(こなみかん)と思いました。

  • 「プログラミングは人類には早すぎたんや……」

エキセントリックバグの数々を見ると、正しく動作するコードを書けるなんて幻想やったんや……という気分になりました。機械に検証させるしかない!

  • 「テストは大事」

ユニットテスト書くだけでコードの質は向上しない、とか言ってる人がいますが、向上します。
ユニットテスト書くやろ、こんな単純なテストが落ちる訳ないやろと思うやろ、実際半分くらい落ちるやろ、テスト通すために既存の実装直してからテスト追加するやろ。これだけでコードが良くなる。
あと、テストがないとまた壊れるというのもあり、テスト書きまくるのは重要だなぁ、と思いました(マジこなみかん)。

次回作にご期待ください!

私もそろそろ次回作(何)を出さないといけない気がしています。

次の戦場はどこにしようかしらん。

*1:オープンソースのプロジェクト名がChromium、それを元にGoogleが出してるブラウザがChrome、BlinkはWebKitから派生したレンダリングエンジンで今はほぼChromiumの一部

*2:オブジェクトのスレッドセーフなコピーを作るテンプレートクラス

*3:std::bind相当の独自実装クロージャ作成ライブラリ