Runner in the High

技術のことをかくこころみ

Reactの`use`とmoizeを組み合わせるといい感じ

最速攻略記事によると、Reactのuseはキャッシュと組み合わせる必要があらしい。

というわけでmoizeを使ってみたらいい感じだった。

"use client";
import { Suspense, use, useState } from "react";
import moize from "moize";

export default function Home() {
  return (
    <main>
      <h1>Suspense</h1>
      <Suspense fallback={<div>Loading...</div>}>
        <Waiter />
      </Suspense>
    </main>
  );
}

const waiting: () => Promise<string> = moize(
  () =>
    new Promise((resolve) =>
      setTimeout(() => {
        resolve("hello world");
      }, 500)
    )
);

const Waiter = () => {
  const [counter, updateCounter] = useState(0);
  const value = use(waiting());

  return (
    <>
      <button onClick={() => updateCounter((c) => c + 1)}>increment</button>
      <div>Count: {counter}</div>
      <div>Waited: {value}</div>
    </>
  );
};

動作確認

state更新の際にはuseに渡されているPromiseは評価されないので、レンダリングが部分的になっている。

waiting関数の評価は初回のみ。

キャッシュあり

ちなみにmoizeでキャッシュしないと、state更新のタイミングでuseに渡されたwaiting関数も毎回評価されるので再レンダリングされてしまう

キャッシュなし

しかし、moizeをただ単に使うだけだと、キャッシュの管理やinvalidationなどの機構が不十分なため実用性には欠ける。

そういう意味では巷にあるSuspenseサポート系のライブラリを使う方がよい。

追記

2023年8月時点ではReactのmainブランチにCache APIでラップされたfetchが実装されているため、将来的にはclient-side fetchでもmoizeなどのキャッシュライブラリなしでUse APIを楽に使える可能性がある。

izumisy.work

Discord誕生以前のストーリー

open.spotify.com

Podcastで聴いて面白かったので、Wikipediaに書かれていない話だけ備忘録的にメモ。

インキュベータ時代

UCバークレーのルームメイトの親戚がインキュベータを始めるため、起業したい若者を探していた。その話に乗っかりシリコンバレーで起業。最初期はマッチングアプリをやったりFlashマルチプレイヤーのunoを作ったりした。

同時期にスティーブ・ジョブズがAppStoreを発表。それを見て「これは絶対来る」と確信し、作っていたものを全部畳んでゲームアプリ開発に全振り。2008年頃。今ではよくあるRPG風味のパズルゲーを作ってたくさんのユーザーを獲得した。

マネタイズの方法は考えてなかった。

OpenFaint時代

自分たちがゲーム開発で用いていたリーダーボードやチャットルームなどのソーシャル機能を汎化してプラットフォーム化するアイデアを思いつく。

簡単なウェブサイトを作り「3日あればあなたのゲームアプリにマルチプレイヤー機能を組み込めます」という謳い文句で宣伝したが、実際にはその当時は金も時間もなく、作れるかどうかは一旦考えずに欲しいと思っている人からFBを集めることに集中した。このプラットフォームはOpenFaintという名前でローンチされる。

マネタイジングとして最初はフリーミアムからの従量課金を試みたが、あまりうまく行かず。マネタイズの方法はちゃんと考えていなかった。資金調達に関しても、当時はスマートフォンが登場したばかりであり、スマートフォン・フォーカスのプロダクトで調達するのは難儀していた。

GREEから買収提案を受け、プロダクトグロースの観点からメリットがあると判断し買収をacceptするも、結果的にはあまりうまくいかなかった。プロダクトを作ることに集中したかったが、ビジネスサイドのディレクションを要求されたりなどして、ソリが合わず結局辞めてしまった。*1

GREEはOpenFaintを買収から約1年後の2012年にクローズしている。

Discord時代

Discordを作ったタイミングはチャットサービス群雄割拠な時代で、非常にcompetitorの多い市場だった。例えばSkypeなどが市場を席巻していた。

しかし、その当時はブラウザで動くゲーマー用チャットというのはなかった。なのでブラウザベースにすればインストールする必要がなくなり、コンバージョンの障壁をなくせると予想した。WebRTCを使えばボイスチャットも実装できるし、自分たちならうまくやれるという自信があった。

当時はスマホゲー全盛のタイミングだったが、あえて最初からPCゲーマーに全振り。PCゲーマーはスマホゲーマーよりもプレーの連携などでコミュニケーションを必要とするはずだという仮説があった。

なお、マネタイズの方法はとくに考えていなかった。

*1:この辺りの内情を知っている人によると、厳密には某M社の執行役員GREEにいたころにJasonの才能を見抜けずに追い出してしまったとか...

最近飲んだコーヒーとロースタリー

いろいろ買ってるので備忘録がてら書き残しておく。なお筆者はそんなにコーヒーガチ勢ではない。

成城石井 マイルドブレンド

コスパの神。正直Amazonではなくたまに店頭でセールやっているときにたくさん買ったほうがいい。

ちゃんとしたロースタリーで売っているようなやつにも味劣りしないのですごい。

TOKYO COFFEE デカフェ エチオピア

デカフェで夜もコーヒー飲みたい&水抽出でデカフェにしてるのでいいかなと思い購入。

安いやつだと麦茶みたいな味のデカフェのコーヒーがあったりするが、当然そんなことはなく無難に美味しい。

入谷珈琲豆店

たまたま入谷に行った時に見つけたコーヒー屋。オーナーがいろいろ教えてくれて気さく。

シングルオリジンだけじゃなく季節のブレンドとかもオンラインで売っていて良さがある。

入谷ブレンド

iriyacoffee.shopselect.net

定番商品らしい。ノリで買ってみたが結構よかった。

デカフェ メキシコ 中煎り

iriyacoffee.shopselect.net

こちらのdecafも水抽出のもの。

味は忘れてしまったが、デカフェと言われなければ気づかないレベルの味。

珠屋小林珈琲

tamaya.coffee

宮内庁御用達のロースタリーらしいので試しに買ってみた。

オンラインでは取り扱っていないようだが、豊洲のららぽの近くにあるスーパーで豆を購入できる。

奮発してブルマンを購入したが、たしかに値段相応のあっさりしたおいしさがある。

ブロワ珈琲焙煎所

www.blowercoffee.com

前に房総半島へドライブしたときに見つけた。だいぶ辺鄙なところにあるにも関わらずそこそこ混んでいるときがある。

たしかグアマテラかなにかを買った記憶がある。なお、ブラウニーがかなりおいしい。

プラットフォーム・エンジニアリングと過去の経験

Publickeyで公開されていたPlatform Engineering Meetup #1のまとめがとてもよかった。

www.publickey1.jp

スライド中でも書かれているように、共通のプラットフォームを作るのがめちゃくちゃ難しいというのは同意。

自分が今年の1月ごろに書いた記事とも若干関連があると思っていて、やはりいい開発組織はプラットフォームという形をうまく扱っているし、その組織構造の結果としてマイクロサービスがアーキテクチャに現れる。

izumisy.work

詳細はボカすが、かつて僕が働いていた会社でも当時流行っていたチーム・トポロジーの輪読会を経て、プロダクト開発組織の中でいわゆるプラットフォーム・チームというものが組成されたことがある。これは、当時分割されていた個々のマイクロサービスに対してオーナーシップを割り当てる形でチームを再組成し、既存のバックエンドにある認知不可を低減させようという取り組みを包含していた。いわゆる逆コンウェイの法則の適用にあたるもの。

そのプロダクトでは早期からマイクロサービスがチームとは関係ない軸*1で分割されていて、バックエンドの開発者は機能開発の際に複数の(ある程度複雑な)マイクロサービスを横断的に扱うことが要求されていた。このようなマイクロサービスとチームの不整合性が、開発時の認知的負荷を増やし品質の低下やバグを引き起こしているのではないかという説が議論に上がっており、その解決策としてオーナーシップを個別のチームにアサインしてみようという結論になった。そして、そのチームのことを「プラットフォーム・チーム」と呼んだ。

「プラットフォーム・チーム」はただ単にマイクロサービスごとの機能開発を担うだけではなく、名前の通り生産性向上のためのリファクタリングや改善の取り組みも同時に行なっていたのだが、チームに対して複数のゴールが存在することで優先度の問題が影響を及ぼした。マイクロサービスにおける機能開発とプラットフォームという立場で生産性向上の取り組みを兼務しているため、優先度の競合によりバックエンドがなかなか完成せずフロントエンドの開発を前に進められない状況が以前よりも多く起きるようになったのを覚えている。そもそものマイクロサービス分割軸の都合上、チーム間でのコミュニケーションコストの増加を避けることもできなかった。

当時の僕はチームの組成や結果に対しては妥当なものだと思っていたが、今改めて振り返ってみればこの組織における「プラットフォーム・チーム」は全くプラットフォームとは言えなく、どちらかと言えばバックエンド開発のためのチームでしかない。

反省と言っていいのか分からないが、正しくPlatform Engineeringの文脈でものを考えるならば、また別でマイクロサービスに対して生産性向上を担う抽象度の高いフレームワークや共通の基盤を専門で行うチームのことを「プラットフォーム・チーム」と呼称するべきだったと言える。通常の機能開発とプラットフォームとしての開発をひとつのチームで共存させるべきではない。

あるいは、プラットフォームという名を冠することがそもそも間違いだったのかもしれない。

*1:どちらかといえば技術的な都合によるものだった

転職活動でいろんな会社のマイクロサービスと組織を見聞きして思ったこと

転職活動でいろんな会社のエンジニアの人と話して思ったことをマイクロサービスの観点で備忘録がてらメモしておく。

よくあるマイクロサービスの分割軸として、業務機能、ユースケース(動詞)、リソース(名詞)あたりが一般的だが、これらどれもがドメインを構成する要素であるため、マイクロサービスに分割してしまうと結果的にソフトウェアの形がビジネスルールの変化を制限してしまうケースの方が多い気がしていた。実際、規模の小さい開発組織でマイクロサービスやってみました〜からのツラミはそういうのが多いイメージで、よくある「マイクロサービスやったけど逆に開発遅くなった」みたいなとこは上で挙げたような粒度の切り方をしている印象がある。

この件に関して、去年末の転職活動のタイミングでいろいろな人に話聞いてみた結果、実際にマイクロサービスでうまくやっていそうな組織は、上で書いたようなドメインを構成する要素でマイクロサービスをやるのではなく、プロダクト開発のための内製プラットフォームを作るような粒度としてのマイクロサービスを取り扱ってそうな印象を持った。

あとは、そもそもアプリケーションを分離しているパターンもそこそこあったが、これはマイクロサービスと言っていいのか謎なので一旦無視する。

内製プラットフォームとは

雑にいうならばドメイン固有ではない範囲を分離してマイクロサービスにしているイメージ。

これは、いわゆるDDDでいうところの汎用サブドメインに相当するものになる。例えばアプリケーションで使っているサードパーティSDKクラウドリソースがあるとして、それを社内で独自のチームを組成して作らせるような雰囲気。メガベンチャーだとそういうチームが大抵ある気がしていて、例えばLINEのVerdaとかはプラットフォーム超えてクラウドなのですごい。

内製プラットフォームを作るようなチームの存在を維持するためには、それ相応のリソースが必要であり、そこに投資できるだけのプロダクト価値と顧客のニーズも必要。なんなら開発組織の規模に比例すると思う。プロダクトがうまくいっていて、開発に投資できる組織はやはり規模が大きいし、だからこそ内製にアドバンテージが出る。

逆に、無駄に早いフェーズでこういうチームやマイクロサービスを組成して抽象度を間違えると、開発組織の中で無駄にコミュニケーションが必要になったり単なる受発注をするだけのチームがいくつも生まれて地獄絵図になる。マイクロサービスの切り方もおかしくなる。

個人的な解釈

プロダクトとしての独自性を作るために業務機能、ユースケース、リソースが変わることは頻繁にあるので、この変化に技術的な都合で対応できないのは本末転倒。正直なところ、プロダクトが持つ機能の独自性で競合とバトルしている時点でそのプロダクトはジリ貧だと思うが、大抵のプロダクトはそうならざるを得ないのでドメインが定まらないのは仕方ないし、エンジニアリングの面でも対応するしかない。この状況ではドメインは常に不安定なのでマイクロサービスとして分割するには適さない。おそらく、業界のプラットフォーマーと言えるくらいのレベルにならないと安定することはない気がしている。

マイクロサービス・アーキテクチャ1版でもドメインへの理解が低い場合にはマイクロサービスは適さない」と書かれていたが、そもそもドメインが"理解できた"と言えるようなエウレカ的瞬間はプロダクト開発においては形を変えつつ小刻みに連続して現れるのであって、ゴールテープのような"究極の理解"のタイミングがあるわけではない。マイクロサービスであることが連続的に発生するドメイン理解と変化のスピードを遅くする原因になっているのならば、それはむしろマイクロサービスがプロダクト成長の邪魔をしている状態と言っていい。そのような事態を避けて、明確に切り離せそうな単位でマイクロサービスの分割をするならドメインかそれ以外か」くらいの粒度になるわけで、そうなればマイクロサービスとして切り出せる選択肢は汎用サブドメイン以外ない。

みんながみんな内製プラットフォーム的なものを作るチームを持つべきかというと、それは当然なんか違う気がしていて、高度な抽象化をするためにはそれ相応のメリットを感じるだけの規模と価値を持つプロダクトとビジネスの存在が前提になる。あと一般に汎用サブドメインといえば認証や通知*1とかがよく出てくるが、そういうのはサードパーティのプラットフォームを使うだけで十分なことも多い。

結局、ギリギリまで外部のサードパーティ・プラットフォームを使い続けて、とうとうそれがプロダクトのニーズ似合わなくなってきた... という時に初めて、ようやく自前でマイクロサービスとして内製するというレベルでよいのではないか。そして、ある程度うまくやっていそうなところはそういうやり方をしていそうな印象を持った。

PS: この記事書いてて思ったが、過去に書いた以下の記事とかなり内容が近かった。

izumisy.work

*1:なお、通知をマイクロサービスとして抽象的に切り出そうとすると意外に難易度が高いという話がある 通知マイクロサービスはアリ?ナシ? - Speaker Deck

2022年を振り返る

とうとう今年も終わりますね

生活

2021年の5月ごろにノリと勢いで土地を買って家を建て始めていたが、今年の2月にようやく完成。今年は入居して新居を楽しんだ。

家と言えば、そもそも家を建てていた2021-2022年の時点でウッドショックと半導体不足がフィーチャーされていて、それだけでも家を建てるという観点ではそこそこ痛手だったが、そこに輪をかけてインパクトを与えるいまの米国経済の状況を見ると、改めて未来ってどうなるか分からんな... という感想。

とりあえず今のインフレをリセットするために2023年春まで米国では今の景気状況が続くという話が多いが、いずれにしても未来のことは予想できないので今できる最善の選択をする以外ないと思う。

仕事

Uniposを11月で退職してTailorにJOINした www.tailor.tech

「日本からYコンビネータに採択されている」「創業者の経歴が強い*1」「プラットフォームプロダクト」とこれからの未来しか感じられないスタートアップだったので、ここに次の自分の人生をbetする以外の選択肢は無かった。基本的に過去や現在には興味がなくて、未来に可能性があるかどうかしか考えてない。

やっている内容をざっくりかいつまむと、TailorはTailorプラットフォームという「プロダクトを作るためのプロダクト」を提供していて、現在自分はその機能拡充をフィードバックするためのPoCをやっている。ソフトウェア・エンジニアとしての面白さはやはり「プラットフォームであること」に起因するところがあり、通常のソフトウェア開発よりも1段抽象度の高い思考を求められていて楽しい。

なんとなくではあるが、OSSなライブラリだったりミドルウェア開発っぽいことをしてみたいという人には合っているような予感がする。とはいえもちろん抽象度が高いぶん仕様も複雑なので、とりあえずどうにかできる胆力は求められると思うが。

とりあえず気になった方は弊社採用ページからどうぞ。Twitter DMも歓迎です。

まとめ

Uniposのときもそうだが「俺が育ててる、俺と仲間たちで育ててる」と言いたいと思えるようなプロダクトに自分の人生を費やしたほうがいい。

1日8時間やってもまだ足りないと思える仕事じゃなければやる意味がない。

www.youtube.com

*1:これがなぜ重要かについてはベンチャーキャピタル全史を読むと早い

コードレビューとオーナーシップ、できる限りコードレビューをしない

前職でフロントエンドチームのスペシャリストとして開発プロセスを考えるポジションにいた。そのときに試してみて良かったなと思えたのはAutoApproveという仕組みで、これは任意のPRにAutoApproveというラベルが付くとGithub Actions経由でPRがGithub BotにApproveされコードレビューなしでマージできるというもの。

コードレビューでは、プロダクトの規模が大きくなっていくにつれ認知的・時間的なコストが嵩む。レビュワーも広汎なドメインや設計レベルの知識が求められたり、人が増えると「これレビューする意味ある?」みたいなPRもレビュワーにバンバン飛んでくる。そうなると、全体的にさらっと見てApproveしたりする。これはもちろんレビューをされる側もそうで、コードレビューという仕組みがあるとなんとなくレビューをゲートキーピング的に捉えてしまいがちなところがある。

なんのためにコードレビューをするか、という意思統一が抜本的に図れていればいいが、それであっても「レビューが通ってるからOKでしょ」みたいな、ある意味自分のコードのオーナーシップを軽く見がちな傾向がコードレビューに対する向き合い方次第では醸成されやすい。これは 「その変更で何かが起きたらひとりで責任を取れ」という話ではなく、ひとりのソフトウェア・エンジニアとしてある程度のレベルがあるなら自律して品質に責任を持てる状態になっていることを期待できるでしょ、という話。

実際、主観的ではあるがAutoApproveの仕組みがあったことで、ある程度本質的にレビューが必要なものだけが厳選されて飛んでくるようになった感覚があった。たとえばtypo修正だったり、内部的になツールだったり、ビューや設計のちょっとした変更であればみんなさっさと入れてしまうし、あとから共有とともにその良し悪しを議論するほうが圧倒的にスピード感があった。

特に前職のフロントエンドはElmで実装されていたこともあり、言語的な特徴*1から仮に大きな変更と言ってもそのバリエーションには限界があることがかなり予測できていた。このあたりは、言語やフレームワークの自由度に大きく依存する。

若干エクストリームな思想ではあるが、そもそもエンジニア採用の時点でレビューが頻繁に必要になるエンジニアを入れないほうがいいというか、前提としてコードレビューがなくても信頼できてガンガンコミットするのを許せるような人材を集めたほうが、プロダクト開発の生産性は高いんじゃないかという気持ちもある。とくにベンチャーやスタートアップならなおさらそうで、組織の最高速度を上げられるなら無限に上げたほうが良いはずだと思っている。

とはいえ、やっぱり人間はある程度の責任を背負わないと成長できない。

余談

とはいえ、冷静に考えるとフロントエンドという領域だからできたみたいな話もある気がする。

言い方には気を付けたいが、バックエンドに比べてフロントエンドのほうが(セキュリティは別として)インシデントのインパクトが小さい傾向はある。たとえばバックエンドで不整合なデータを生み出すようなコードが混入すると、そこそこ重めの復旧作業が発生することが考えられるが、フロントエンドでそういった尾を引くインシデントを起こすリスクは少ないのではないか。

壊れたら気軽にロールバックできるようなリリースプロセスを作り、E2Eほどではないにしてもスモークレベルの自動化テストを用意して、コアの機能以外は壊れても後から余裕をもって修正をリリースできるようにすればいい。もちろんプロダクトやビジネスの性質にもよるが、それでもフロントエンドのほうがやっぱりアグレッシブになれるような気がしている。

*1:言語仕様が小さくてできることが少ない、フレームワークと言語が統合されている、型システムでテクいことができない、とかそういう特徴を言っている。

クラウドバンクを3年間続けた結果

2020年ごろにこんな記事を書いていた。

izumisy.work

しばらくの間ずっとほったらかして運用し続けていた。

2022年10月現在では結果的に累計で60万ちょっとくらいの利益が累計で出たらしい。

2022年10月ごろの状況

いまは少しづつ投資信託のほうに配分を移しているのだが、基本的に300-400万円くらいを定常的にクラウドバンクの運用に回していたので、それくらいの額で結果的に60万レベルのリターンがあったと考えるとそんなに悪い投資ではなかったかな、という印象。

しかし年間の利回りだけで考えると、正直クラウドバンクよりも投資信託のほうが断然いいものが多いので、それでもクラウドバンクで運用をし続けようという理由が自分のなかでは特になくなってしまった。とはいえ、一部のソーシャルレンディングで印象の悪いものがちらほらいたものの、結果的にクラウドバンクは一番信用できるソーシャルレンディングのプラットフォームだったかな、とは思う。