Viceroyを眺める

便利そうなプレスリリースが出て、色々調べてたら開発用ローカルサーバーのコードが見つかったので土曜の夜の暇つぶしに眺めてみる。

開発用ローカルサーバーのコードを読んだところでなんだという感じなのだが....

登場人物

概念

  • downstream request/response: クライアントから飛んできたリクエスト/レスポンス
  • upstream request/response: バックエンド系に飛んでいくリクエスト/レスポンス

ゲスト側

fastly create

Fastly Compute@EdgeSDKリポジトリは非公開のようだがcrate.ioやdocs.rsでホストされており、コード自体は見れる。

fastly-sys

上述のfastly createが呼び出すFFIextern "C"で定義. 要はユーザーの書いたwasmモジュールにimportされる関数のシグニチャを定義しているにすぎない。基本なんでもハンドルを経由して動かす。

ホスト側(Viceroy)

MozillaからFastlyに移籍したWasm/Rust組がIssueとかでよく見かける(当たり前)。

Viceroyrev. 28e4078e時点)

fastly CLIfastly compute serveすると起動する「開発用ローカルサーバー」の実態

今のところ未実装なものが色々あるが、読んで遊ぶには十分。

Fastly社の各種発表を聞くに、商用環境のホスト側はlucetでwasmモジュールAOTコンパイルした上で実行しているらしい。一方、こちらはwasmtimeを使っているのでサーバー起動時にwasmtime::Moduleを生成、各リスエストごとに実行時に環境(後述のSessionとリンクしてwasmtime::Instanceを作って実行する。

アプリケーション自体はhyperを使って書かれているのでいろいろasync/awaitする.

compute-at-edge-abi

witx(初めて知った)で記述されたABI定義。fastly-sysに対応する定義が記載されている。

Viceroyではwiggleの提供するprocedural macroを用いて、viceroy_lib::wiggle_abiとの対応を取る

viceroy_lib::session::viceroy_lib

downstream requestごとに生成される. 上述のcompute-at-edge-abiで定義されたABIもほぼこの上に実装されている.

処理の流れ

作るのがめんどくさいのでシーケンス図は省略

一番美味しいところはExecuteCtx::run_guest()を読めばよい.

各downstream requestに対するゲストコード(wasmコード)は、tokio::task::spawn()される。デスヨネー。

SessiontokioのchannelのSenderを持っているので、downstream responseが打ち返されたら(fastly_sys::fastly_http_resp::send_downstreamが呼び出されたら)、渡ってきたSenderに詰める.

つまり、ゲストコードがfastly::Response::send_to_clientfastly::ResponseHandle::stream_to_client )やfastly::Response::stream_to_clientfastly::ResponseHandle::stream_to_client )を(ユーザーまたは#[fastly::main]によって生成されたコードが)呼び出すことで、処理がホスト側に渡る。

もちろんホスト側ではそれを待ち構えているので、うまいことハンドルして終わり。

感想

小さいしRustで書かれてるので読みやすい。Proxy-Wasmな、Wasmな任意コードを動かす配信サーバーの実装例 + ユーザー向けSDKの作り方としても読める感じだった。

ただFastlyというCDNサービスを使う側の視点としてViceroyを見た場合、あくまでもFastly Compute@Edgeのユーザー用ローカル開発シミュレータ専用に実装されたようにも読めるので、本番との挙動の差異をどうやって埋めていくかが気になるところ。テストスイートとかどうするんだろう?

謝辞: #web24 のperformanceセッションありがとうございました

書こう書こうと思っていたらすっかり7月になってしまいましたが、以前、宣伝をしたWeb 24のPerfomanceセッションの観客の皆様、ならびに共演者各位ありがとうございました。

saneyukis.hatenablog.com

....楽しんでもらえたのかな?

登壇者の自分個人としては、「ああ、もっとプロレスに持ち込めれば良かったなあ」とか「もっと共演者を挑発してコンテンツ性を高める制圧力があればなあ」と反省点ばかりです。

また、内容についてはハイコンテクスチュアルに成らざるを得ないのはともかくとしてWebの話をしすぎたのがちょっと悔しい。 ソフトウェアパフォーマンスってWeb固有の問題ではなく.... そもそもWebってなんだよという話なんですが、ソフトウェア工学的な話の中にWeb固有の事情があるという位置付けだと思っているものの、そういう方向に話を持っていけなかった自分の制圧力の無さにちょっと後悔している。

言い訳をする気になれば「とはいえ話のフォーカスを作らないといけない」とか色々できるんですが、自分の話術の未熟さの方が反省点として勝るので、ここらへんでやめておきます。

楽しんでいただけならありがとうございました。

また次回、何かでご縁がありましたら、その時はまたよろしく。

宣伝: #web24 のperformanceセッションに出演します

セッションオーナーのnodagutiさんにお声がけいただいて、Web 24というオンラインイベントのperformanceセッション(5/8(土)の11:10~12:40)に出演することになりました。

なんとか24….. 24時間その話をする...... うっ、頭が......

普段はこういう宣伝はあんまり書かないんですが(書いてもTwitterでチョロっと書くだけだったりなのですが)、主宰筆頭のJxckさん曰く「出演者込みで熱量を作っていきたい(要約)」ということで、確かにそういうのって大切なことで、出演者が盛り上げなくて誰が盛り上げるんだと珍しくブログに書くべく筆をとった次第となります。

イベントについて

さらなる詳細や共演者各位の紹介、ハッシュタグについてはイベント詳細ページをご覧ください。 僕が下手に説明するよりも、そちらを参照する方が間違いがないでしょう。

完全ぶっつけ本番のイベントで、セッション開始直後の出演者紹介タイムとイベント全体の趣旨の説明以外全く打ち合わせしていないガチンコプロレスとなります。「セッション中の 休憩の為の 参加者アンケートタイムなどやらんでよし!全力で殴り合え!議論しなければ生き残れない!」タイプのイベントになるらしいです。

しょうがないので議論で負けそうになった時の反撃用に一斗缶を用意しようかとも思ったのですが、これはオンライン配信イベントであり、画面の向こうに投げることができないことに気づき断念しました(これは番組上の演出であり、当日はCode of Conductに則り安全にイベントが進行されます)。

あと、「スパチャで限界スパチャ芸をやりたいんだけど無いの?」との質問を友人から頂いたのですが、本イベントはそういうのはやらないとのことなので、どうしても課金したい方(いるかはわからないけど)は、応援したい団体・プロジェクトやお店への寄付または課金で代用してください。

出演経緯

さてさて。

上に書いたような電流デスマッチイベントなわけですが、とりあえず自分を呼んでくださった理由をセッションオーナーのnodagutiさんに軽く聞いたところ「小手先の”パフォーマンス改善テクニック”にとらわれない,本質的な改善を志向されていた印象がありまして」との返答をいただきました。

他の皆さんはさておき、このふわっとした感じ、これは僕に限っては専門家として呼ばれたんじゃなくて、熱意 + プロレス適正の高さ + ちょうどいいところにGW暇そうな人間がいたからで呼ばれたってヤツなんじゃないか? きっとそうに違いない。とりあえず精一杯バックドロップをかけられないかタイミングを狙っていきたいと思います。オラッ!見せ物だぞ!

いやー、過去に色々登壇したりしたからその実績だと思いたい。思いたかった。仕方ない。仕方がないので凶器になるパイプ椅子を探そう。

あと、自分はこの手のオンライン配信イベントは初参加で不慣れなので、とりあえずプロに学べということで声優の出るラジオやYouTubeの番組をいくつか視聴して整えています。とりあえず番組固有の挨拶を考えないとダメなのかな。

よろしくお願いします

そんなこんなで、当日は頑張ってやっていくのでよろしくお願いします。お暇がありましたら覗いていただければ幸いです。

ちなみに これが一番重要なんですが、アーカイブ配信は無いらしいので、一期一会のライブ感をお楽しみください

Reactのprops/contextの使い分け

Reactのprops/contextの使い分け

仕事先でたまたまこれの話になり、個人的に思っていることをまとめた。 公開したのは、時々見かける「どっちを使うべき?」みたいな議論に 自分も混ざりたかった 思うところがあったから.

「とにかくpropsでいい」と自分は考えている。

なによりReactは書き方に詰まった場合に、フレームワークライブラリ固有の事情を考慮して解決するというよりも、実装や設計上の問題が一般的なプログラミングパターンの範疇の発想で解決できるのがよい

前提

以下のように考える

  • React/preact のコンポーネント = 通常のclassや関数
    • 状態を隠蔽して抽象する
    • 最近は冪等性がどうとかReact語るときにあんまりいわなくなったけども....
  • props = 関数やメソッドの引数(入力)
  • context = グローバル変数(モジュールグローバルな変数)

実装の指針

1. まず引数(props)でどうにかできないか考える

  • グローバル変数に依存しないクラス・関数の方が、テストもメンテナンスしやすい
  • 大抵の場合はpropsでどうにかなる

2. propsでは「めんどうくさい」「うまくいかない」と感じた時にグローバル変数(context)を、やむを得ず使う

以下のようなケースで、グローバル変数を使った方が良いのか一回落ち着いて考えた上で、それでもやっぱりグローバル変数(context)を使った方が良いなと思ったら使う

  • スケジュールの都合、propsよりもcontextを用いた方が簡単である
  • ページ(アプリケーション)中で同じ値を、必要な箇所で参照している
    • テーマ機能の実現
    • ページの初期化時に取得した認証情報を触る
  • propsで渡すと、どうにもコードが簡潔に書けない

注意点

  1. Contextを利用する場合, <Context.Provider/>で囲った箇所(ツリーの子孫)は、Contextの値が更新されると全て再実行される。そのため、性能問題が発生しやすいので、値が頻繁に更新されるものは、上の基準に合致していても、なるべくpropsで渡すようにする
    • そもそも自分はなるべく使わないのでそんなに困らんのだけどね.....
  2. Contextを利用する場合であっても、なるべくuseContextの呼び出し回数を最小限にする

コードレビューの指針

以下を見る:

  1. そのcontextの影響範囲・利用用途は適切か
    • 影響範囲が広い場合、注意深く検討する
  2. 気になるなら実装者に「propsに直してみるのはどうだろう?」と聞いてみる
    • 実装者に任せてみる
  3. 究極的には「どんなに”ひどい”設計・実装でも、影響範囲が小さい(使用箇所が限定されている)ならば、大抵は問題ない」ということを留意する
    • 困ったら、その時にリファクタしたり、丸々書き直せば良い
    • あとで修正しやすくするために、テストケースの有無や妥当性を検討する方がよい

Q&A

Q. propsでなるべく渡そうとすると、どうしてもpropsで受け取る値が増えてしまうけど、どうすればいい?

<Hello bar1 bar2 bar3 bar4 bar5 bar6 bar7 bar8 bar9/>

のように、たくさんの値が必要になってしまう場合. 以下のようなアプローチが考えられる

  • 「ひとつのコンポーネント(関数)で多くのことをやろうとしすぎている」ことが多いので、困難を分割する
  • 関連する値をオブジェクトに一度まとめて渡す
    • ValueObjectを作る....というか一般的なモデリングの話というか
  • render propsprops.chidlrenといった手法を試す

背景

そもそも自分はContextを使わない。

  • ライブラリや他人の書いたコードがそれを要求してくる
  • 設計上とスケジュールの制約上、どうしてもContextを用いた方が早く作れる
    • かつ、値がほとんど更新されない

場合くらいしか使うことも使った記憶もなく、自分で設計を決められる場合は

  • 全体に影響がある値は、ルートにStoreないしStateを用意する
    • 余裕があればgetter setterを別のインターフェースとして定義する
  • そしてそれをひたすらにバケツリレーする

スタイルでゴリゴリやってしまう。

グローバル変数のたとえもあるし、「選択という手間を省き、その分の思考のリソースをより根本的な設計を検討するのに注ぎ込みたい」意味もある。 また、常にpropsを用いることで、パフォーマンスやリファクタの問題をシンプルにする、という意味合いもある。

あと、自分がReactやWebクライアントサイドアプリケーションに関して一番熱心に考えていた頃はLegacy Context APIしかなかった結果が、このスタイルに自分を規定した気はする。あの頃の「機能としては存在するけどなるべく使うな」の趣を思い出せば、自然と基本はprops一択になる。

対して。現在のContext APIはだいぶよくできている。 しかしながら、グローバル変数の例えもあるし自分からは積極的に使うほどでもない、みたいな距離感。

そんな感じなので、正直、「Contextで困ったらプロファイラ使って測って遅いところ削ったり、必要に応じて抽象化のリファクタすりゃいいじゃん。別にReact専用の体系的なあれこれ要らないよHAHAHA」程度の気持ちだったところ、ケーススタディガイドラインとしては以下のような切り口もあると嬉しいのではないかと同僚からフィードバックをもらった。

たとえば

  • 巨大なContextは作るな分割しろ
  • 直接 useContext()は使うな、カスタムフックの裏に隠して最適化の余地を残せ

みたいなのあるじゃないですか、と。

そう言われると、ReactのContextで困るとそういう感じのことやることになるよなあ、てか職場を問わず毎年1回〜2回はそういう変更のコミット作ってたわ。確かにね。

ただ、それらは自分にとっての体系的な何かというよりは、一般的なプログラミングのグッドプラクティスや技法の域を出ず、React固有の何かとして特筆する気になれないのであった(というわけで、ガイドラインのContextベストプラクティスの章は彼に任せることにした)。

IE11とその他ブラウザの最新版ってどのくらいベンチスコアに差があるのか(手抜き版)

IE11のリリースは2013年秋。それから7年間で競合がつっこんだ投資の結果、ベンチマークスコアに差はどのくらい生まれているのかを知りたかった

注意点

  • EdgeHTMLを実行できる古いWindows環境は手元にないので無視する
  • Microsoft Edge (Blink)はどうせBlinkでしょ….ということで無視する
    • Edge限定のパスとかMSが用意してないことに掛ける
  • もはや大体のベンチマークは動かないので、ノー修正で動くものだけトライする
    • 結果, JSとDOMだけの計測に
    • たぶんpolyfill入れたりbabel通せば動くとは思うが、とりあえず今回はスキップする
      • MotionMarkは動かしたかったが…..
    • そのうち真面目に色々動くようにした上で再計測にしたやつをやるかも

環境

  • Windows 10 20H2
  • Dell XPS 13 (2015)
    • CPU: Intel Core i7 5500U 2.4GHz(物理2コア4スレッド)
    • RAM: 8GB
    • GPU: Intel HD Graphics 5500
  • ハイエンドではないけど、まだまだローエンドってわけでもない、はず

スコア

JetStream 1.1

IE11 Firefox 85.0 Chrome 88.0.4324.146
Latency 74.477±18.065 75.946±22.499 47.194±22.116
Throughput 69.304±4.1786 144.56±15.191 191.58±125.61
Geometric Mean 71.482±9.9780 109.16±20.701 103.91±58.452

Speedometer 1.0

IE11 Firefox 85.0 Chrome 88.0.4324.146
Score 23.6±1.9 89.9±2.8 125.4±0.81

いろいろあった

I'll leave the current job at the end of December. The reason is a difference of a direction of my musicality from the company's one.

Of course, there were bunch of things. I can talk about their details but I seem it would not be nice case study. I can only say the difference of the direction. I think everything was caused by it.

Next year....... I'm planning to start a work as a freelance. I know well that this is not a best direction for me. However, I don't have any other choice. One thing I can say for sure is that I will not have a plan to work as a freelance for many years - ideally I'd like to finish and join to a nice company in several month~1 year.

Happy holidays. Have a happy new year.

アートとサイエンスのはざまで

例えばパフォーマンスエンジニアリングは定式化されたアクティビティをどれだけ回していくかのサイエンスだと思う。けれども、一般には秘伝の最適化手法を感性で駆使したアートのように思われていることが多いのはなぜなのか。「〜すると速い」みたいな真偽不明のマントラが多いからそのように見えるのか。

僕からすると、ソフトウェアの設計やリファクタリングの方がよっぽどアートだと思う。問題構造をどのように認識して、どのような形であるべきかを解いて、具体的なコードとして落とし込んで行くアクティビティであって、それは思想や哲学の叙述という行為に近しいからだ。パターン言語とかもあるけれども、ある思想体系において理論立てられた説明と用語を用いているという感覚。