インフラと非開発者

0時に寝て5時に起きて7時に起きた。

インフラのドキュメント作成の続き

昨日はインフラ構成図を主に書いていたが、今日は引き継ぎのために wiki に概要を書いて補足事項なども肉付けしながら、私がやったことや今後運用していく上で知っておくべきことなどをまとめていた。それと同時に backlog の wiki の階層構造なども見直していた。backlog の wiki はタイトルに / を含めることで階層構造を表す。実際の url はエイリアスリンクが使われていて、タイトルとは無関係なので wiki のタイトルを変更することで階層構造が変わる。これはこれでお手軽とも言えるけれど、この階層以下のドキュメントをすべて移動したいといったときは1つずつタイトルを変えないといけないので面倒になる。デイリースクラムのときに来週のインフラ勉強会の時間もスケジュールを抑えてもらった。おそらく1回では終わらないのではないかと推測するが、説明してみて開発者の反応もみながら2回目の有無を決める。

さらに「プロダクトオーナーのためのインフラ入門」というタイトルで別のドキュメントも書き始めた。他の重要な業務がなくて暇だと言ってしまえばそうなのだけど、非開発者向けにクラウドのインフラや自分たちの web システムをどう理解してもらうのがよいか、私自身、試行錯誤で答えをもっているわけではないが、難しいからプロダクトオーナーはインフラを理解しなくてよいというつもりもない。以前からプロダクトオーナーが「自分たちもインフラがどうなっているのかを理解したい」というコメントを何度か聞いていたので筆を取った次第だ。技術的な詳細は理解できないだろうが、いまどきのインフラにおいてどういった概念や考え方が重要なのか、なぜこのような複雑なインフラになってしまっているのか、そうした背景を理解してもらおうと考えている。初めての試みなので、後日やってみて反応をみてふりかえりしようと思う。

インフラと引き継ぎ

0時に寝て6時に起きた。

インフラのドキュメント作成

契約終了まであと1ヶ月半。私が唯一引き継ぎしないといけないものにインフラがある。

引き継ぐ前のインフラは本当にひどい状態だった。手抜き工事のまま放置されたような状態だった。cdk のコードから実際のインフラを構築することはできなくて、コード化されていないところを aws のマネジメントコンソールから手作業で設定していた上、どこを手作業で設定していたかの情報は一切残されていなかった。新しいインフラが追加されるときに cdk のコードと乖離があるからデプロイできなくて、それを前任者は直せなくて私が引き継いだという経緯がある。私が1ヶ月ほどかけて30以上の pr を作ってコードと実際のインフラをほぼ完全に同期させた。その過程で3回ほど (テスト環境ではあるが) 障害も発生させている。デプロイしたら手動設定が消えて壊れてしまう。何が手動設定で何がコード管理なのかの情報が何もないのだからデプロイしてみないと動くかどうかわからないという状況だった。そのため、現在のインフラは私が作り直したと言っても過言ではない。cdk のバージョンも v1 から v2 にアップグレードした。半分以上の cdk のコードは私が書いたと思う。その引き継ぎならびにドキュメント化の作業にようやく着手した。これまで書いてなかったのはインフラを管理しているのは私だけだったのでドキュメントなくても運用上の問題はなく、ドキュメントタスクの優先順位が低かったから。今日は draw.io で aws のシステム構成図を書き上げて、wiki のインフラドキュメントの再構築に着手したところ。

今週中に引き継ぎのドキュメントを書いて、来週ぐらいからインフラ勉強会やって引き継ぎを完了させる予定。

コワーキングから学ぶコミュニティ

0時に寝て2時に起きて5時前ぐらいまで本を読んでまた寝て8時に起きた。昨日の続きでちょっとした画面の改修をやって、小さいタスクを2つほど片付けて、それでもやることなくて暇だなぁ。

backlog-github-integration-action のアップデート

backlog のライブラリのバージョンが上がっていたのを少し前にみかけていたので更新してリリースした。

コワーキングのオンラインイベント

先日のカフーツさんのトークイベント 同様、9月のイベントに参加した。前回は急遽スケジュール調整をしたせいか私1人だったけど、今日は6人の参加者がいた。私以外はコワーキングスペースを運営している人みたい。コワーキングと街づくりといった内容が今日のテーマだったみたい。その事例の1つとして オトナリ[島根県雲南市] を教えてもらった。成功事例の話しを聞いていると共通点の1つとして主催者が地元の人ではなくても、その地域に移住して運営しているという。オトナリも東京のコンサル会社が受注してコワーキングのビジネスを始めたものの、その会社の社員が東京から移住してまでその地域の街づくりに参画しているという。その熱意の違いが正否をわける要因の1つであろうと私は感じた。以前、神戸市さんとコミュニティについて雑談した ときも、あえて言わなかったけど、職員自らではなく業者に委託して運営しているようなコミュニティではまったく運営の取り組みは異なるだろうと思う。他にも コミュニティ財団 という財団法人を作って運営している 愛媛県 西条市 の事例なども教えていただいた。

その後、参加者個々のコワーキングスペースの運営者のお悩み相談みたいなやり取りをしていた。私だけ運営者じゃないのでちょっと浮いてた。お前何ものやねん的なw あと箇条書きで書いたものをマインドマップに変換する Transno というエディターがあるらしい。私は手書きでマインドマップを描くのでこういったツールは使わないけれど、ツールでマインドマップを書くのが好きな人には向くのかもしれない。

蓋然性という言葉がよくわからなかった

0時に寝て7時に起きた。朝からタスクの詳細をヒアリングして web api と画面を作るだけの簡単な作業。しばらく (1-2週間ぐらい?) は暇な日々が続きそう。

蓋然性 (probability) と可能性 (possibility) の違い

わかりやすかった。

夏目漱石が授業で言った例では、「教壇で喋る講師が逆立ちする可能性はあるが、蓋然性はない。」というものがあります。

「判例の用いる確率の用語」~元公務員講師のコラム~

なんとなく稼ぐ

次の4つの手法による収入を passive income (受動的な収入) と定義している。

  1. ソフトウェアとデジタル資産を売る
  2. ブログを始める
  3. 自分の youtube チャンネルを始める
  4. フリーランスオンライン

それぞれみていくと、ソフトウェアを売るというのはアプリストアに代表されるようなマーケットプレイスで販売すること。デジタル資産とは電子書籍など。ブログは medium のようなサブスクリプションを使う。youtube はコンテンツを作って広告収入を得るかな。オンラインでフリーランスとして副収入を稼ぐという方法。どれもよく知られた当たり前の手法だけど、簡潔にまとまっていてわかりやすかった。

スキルの定量化とお仕事探し

0時に寝て7時に起きた。直近は日曜日はだらだらしてたんだけど、すんなり起きれた。

お仕事探し

offers さんのカジュアル面談 の雰囲気から企業に直接応募するプラットフォームの方が、私の経歴や実績の詳細を確認しやすいので面談に進みやすいのではないかとみている。そこで findylapras のプロフィールを作成してみた。これまで oss 活動やブログなどでアウトプットしていた資産がたくさんあるのでレベルはしょぼいにも関わらず、これらのプラットフォーム上ではそこそこよい数値がアルゴリズム的には算出される。プラットフォーム側としては転職やエンゲージメントを高めたいという意図があるから、ゴーストアカウントのようなものも含めて算出すると普通の人は高めの数字が算出されるのではないかと推測する。

findy さんのスキル偏差値によると、想定年収予測は1060-1160万円らしい。この数値は起業する前のサラリーマン時代の年収に近いのでそんなにずれてはいない。lapras さんの公開プロフィール によると、技術力が4.01で約170万人中668位だというのは上位 0.04% に属することになってしまう。んな、あほなという思いはある。とはいえ、自己申告の経歴をいくらでも盛れる職務経歴書よりも、客観的なアルゴリズムで評価できる指標の方が絶対値が適切かは置いておいても、相対評価において他の候補者と比較できるのを好む採用担当者もいるだろう。匿名の一般的な職務経歴書を用いる remogu さんの選考 は書類選考でばんばん落ちまくる。それに比べたら、アルゴリズムで相対的によい数値が出ているプラットフォームの方が面談に進みやすいのではないかという話し。本当にそうかどうかの仮説はこれから検証する。

google の従業員が働いていないという発言の真意

昨日たまたま medium のダイジェストでみかけた記事を読んだらおもしろかったので、なるべく余裕のある日は medium の記事を1つ読むようにしてみようかと思う。言うても deepl を使って斜め読みして大意を掴む程度なので日本語の記事を読むのとそんなに時間が取られるわけではないと思う。今日は次の記事を読んだ。

プログラミングにおける生産性とはどういうものかを説明しつつ、google の ceo がいう生産性が十分ではないという発言の真意は、従業員が業務時間にさぼっているとか怠慢だとかいう意味ではなく、google のビジネス全体がこれまで達成してきたのと同じ業務時間では期待した成果を達成できなくなってきているのではないかと考察している。

At some point, productivity measurement becomes Schrödinger’s cat.

また著者の引用?では生産性の計測とはシュレディンガーの猫のようなものだという話題もおもしろい。どんな会社もある時点での生産性の測定はシュレディンガーの猫のようなものになる。セグメントを分割し過ぎると返ってストレスとなり、余計な混乱を招き、計測そのものが生産性を低下させる。生産性の測定はマクロレベルでやるのが理に適っていて、工場時代のマネジメントをもつ amazon は大量の人員削減をしつつも成し遂げた。google のようなワークカルチャーをもつ会社ならその気になればスマートにできるだろう。一方で google という会社はすでにリベラルな極みにある企業文化をもっているため、生産性を測るような試みは組織全体に大きな感情的ダメージを与えるだろう。その結果として amazon と同じような道を歩むのではないかと。

シュレディンガーの猫がどういう意味かもわからなくてそれも読んでた。

キャリアは知識と経験の差分でわかる

23時に寝て2時に起きてその後どうしていたかあまり覚えていないが気付いたら8時だった。

ストレッチ

今日の開脚幅は開始前160cmで、ストレッチ後163cmだった。今週も全然ストレッチできなかったのになぜか数値はよくなっていた。ストレッチを受けていて調子の悪さも感じなかったので気候が過ごしやすくなってきて体調がよくなった結果として普段の生活における活動量や新陳代謝などにも影響を与えているのかもしれない。トレーナーさんからは涼しくなったのだから運動をしてくださいと言われた。ほんとその通り。

知識と経験

たまたま目を通した medium のおすすめ記事に出ていて、タイトルにひかれて斜め読みしたらおもしろかったので後で deepl を使って精読した。最近は英語の記事を deepl で訳して読んでいる。まず deepl で全訳した後に文脈から訳文の意味をとれなかったり、明らかにおかしいところだけを手直しする。著作権的に機械翻訳を公開はできないため、その翻訳内容は課題管理システムのイシューで管理している。この記事だと手直し数回ぐらいで大意を読める。普段、英語の記事を日本語アカウントで紹介することはないんだけど、これは素晴らしい内容だったのでそのまま共有することにした。軽く所感も書いてあるが、課題管理システムのイシューにはさらに詳細な分析やコメントも残している。

多くの若いチームでは課題管理の重要性を理解していない。その無理解の原因の1つとして、ものごとを検討したり判断したりした時点では正しかったことが未来のある時点で誤りになってしまう可能性を想像できないからだと私は考えている。記憶と忘却の仕組みから前日のことですら半分以上忘れてしまうので数ヶ月前の詳細など、ほとんどの人は覚えていない。にも関わらず、日々の小さい判断の積み重ねや意思決定の履歴を記録として残さないのはなぜだろうか?それはその詳細があとで重要になるかどうか、多くのケースでその発生時点ではわからないからだ。例えば、システムのアーキテクチャに関して言えば Architectural Decision Records (ADRs) というドキュメントが提唱されている。アーキテクチャのような大きなものでさえ、明示的に残さないと経緯がわからなくなるのに、もっと小さい粒度である日々の開発や運用の誤りを、一般の (普通の) 開発者がその発生時点から数ヶ月や数年経ってふりかえって見直すことができるだろうか?いやできないというのが、多くのチームやメンバーをみてきた私の所感だ。多くのメンバーは過去のある時点の見逃しや判断ミスをなかったことにしようとする。それは無意識にしろ意識的にしろ起きやすい。客観的に詳細を確認できればなかったことになってしまうのは仕方のないことでもある。

私は課題管理システムのコメントに、こういう状況からこう判断したとか、誰それと相談してこういう事情でそうしたとか、自身の感覚からとくに意味もなく決めたとか、常々なぜに相当する内容を残している。そして、あるとき過去の経緯を見返して、そのときの判断は適切だったか、過去のある時点で気付けたはずのことを見逃してなかったか、見逃していたとすればどうすればその時に気付きを得られたか、というふりかえりを日常的なチケット整理の一環として実践している。件の medium の記事にはなぜそれが重要なのかの概念を書いてあるように私には受け取れた。課題管理 + 情報共有の需要な概念の1つだと認識して寝かせておこうと思う。

若い会社とのエンゲージメントを図る

23時に寝て5時だと思って3時に起きてそのまま家事をやって5時から働いてた。早起きすると暇つぶしのように溜まっているタスクをこなし始めるので早起きは三文の得というのは本当だ。非稼働日だけど、午前中に次のタスクの要件のヒアリングだけやっといて、月曜日の朝一から作業できるように調整しておこうと考えたが、今日は開発リーダーが休みだったので何もしなかった。

カジュアル面談

Offers というサービス でみつけた会社にカジュアル面談を申し込んでいた。エンジニアリングマネージャーを業務委託で募集しているのは珍しかったのでその背景などを聞いてた。面談してくれた方はテックリードと言っていたが、この人も副業で手伝っているらしい。雰囲気的に若い会社のようで正社員はほとんどいなくてチームのメンバーが10人ぐらいのうち正社員が1-2名だという。基本的に外部の寄せ集めメンバーがそれぞれ副業や業務委託で空き時間を使って開発しているといった話らしい。8時間/週といった契約のメンバーもいるとのこと。どんな人を採用するにしてもまず業務委託から始めるというのがその会社の方針らしい。信頼関係という視点からみると、このような経営者にとって都合がよい労使関係を嫌う人もいるのではないかと思う。一方で私は雇う側も働く側もお互いにマッチングしないときの不幸を防ぐには1-3ヶ月ぐらい働いてからお互いに望むときに採用するといったやり方の方がよいと考えている。実際にマッチングしない人の場合は1週間で見切りをつけるとかあるらしい。私自身、初めてお手伝いする会社は最初の3ヶ月とかは1ヶ月契約でも構わないと伝えることがよくある。その後、お互いにマッチングするなら3-6ヶ月の契約期間に延長したいと交渉する。20年働いてきて、過去に試用期間で解雇されたことや1ヶ月で即解約になったことはないので一定の自信もある。

テックリードが若かったので組織もチームもメンバーも若いのだろうという印象を受けた。業務的にはお互いにマッチングしているように私からは思えた。あとは単純にテックリードが話してみた感覚や相性で私のようなベテランを求めているかどうかで次の選考の有無が決まるのではないかと推測する。次があったら正社員の人とも話してみたい。

v-data-table のカラムのソートがよくわからない

23時に寝て3時に起きて軽く apple イベントをみて寝て6時に起きた。

画面周りのリファクタリング

週明けに私が作った画面が本番環境にリリースされて運用を経てフィードバックが返ってきた。主には使い勝手の改善や要望だけど、何にしても実際に使ってもらってフォードバックがくるのは楽しい。丸1日リファクタリングしていて要望があったものはすべて改善できた。インフラ・バッチ処理、サーバーサイド、フロントエンドのすべてを担当しているから私が関わっているところなら適材適所にリファクタリングできる。システム全体を通してやりたいことを独力でできると楽しい。これは人間の独占欲や支配欲を刺激する。おそらくマズローの欲求でも高次の欲求に属するのだと思う。

v-data-table の props headers でカラムの値に対してソートができる。ソート可能に設定すればあとは自動的にやってくれるのかと思いきや、自分で key function を実装しないとソートはされるけど正しい並び順にはならない。key functoin の返り値が number なので -1, 0, 1 の値でソートの入れ替えを実現しているようにみえる。javascript は true => 1, false => 0 と評価されるので単純な比較演算の結果からは意図したソートにならないからではないかと推測する。このやり方が正しい実装かはわからないけど、次のような key function を定義してあげることでソートを実行したときに意図した並び順になることを確認した。すべてのカラムにこんな実装書くの?というところに懸念はある。

{
  value: 'date',
  sortable: true,
  sort: (x: Date, y: Date) => {
    return x < y ? -1 : 1;
  },
},

ドキュメントを書きながら思うこと

3時に寝て7時に起きた。眠れない。

github リポジトリとシステム間連携

社員さんが運用対応に忙しくてスプリントタスクがなくなって暇なのでドキュメントを書いてた。github に新規リポジトリを作成したときに行う初期設定の作業が増えてきた。大半は私が導入した仕組みや機能のための初期設定になるが、私はリポジトリの管理権限をもっていないので、社員さんにお願いして、この設定して、あの設定してとお願いして対応してきた。もうすぐ辞めるので引き継ぎできるようにやっていることのドキュメントを整理した。

  • slack 連携
  • backlog 連携
  • github
    • pull requests テンプレート
    • github actions
      • github apps
      • github environments

リポジトリと他システムとの連携を効率化しようとすればするほど設定や背景が煩雑になる。とくに認証や権限周りのセキュリティを考慮した仕組みはサービスとのトレードオフになるので設定が面倒になりがちではある。とくに github actions のワークフローは 【登壇報告】JJUG CCC 2022 Spring で語りきれなかった技術的なお話 にあるように、世の中のプラクティスに依らず、私が設計して整備したものなので他メンバーにとって身近ではない。

backlog の wiki にプロジェクトのドキュメントを書いている。開発メンバーでドキュメントを定期的に書くのはほぼ私だけで、他メンバーはほとんど書かない。なぜそうなるのかな?と考えたときに思いつくことの1つとして、開発全般の業務としてやることを、誰でもできる汎用的な仕組みに落とし込むことを考慮して設計していないからではないかと思う。あるアプリケーションが内製/外部システム/外部ライブラリに関わらず、こういう機能や仕組みを使って、こんな課題を解決して、こんな機能を実現していますという構成にはなっていない。発生している問題に対して動けばいいといったレベルでしか開発していないから、本来どう在るべきなのか、どういった設計思想なのか、今後はどうやって保守していけばいいのかの指針を提供できない。これは私の言葉だと設計ができないということと同義だと思う。他に思いつくこととしては、既存アプリケーションにない新規の仕組みを定期的に設計しているのは私しかいないのかもしれない。言い換えれば、言われたことしかやらない人しかいない。

スクラムやっている人たちと雑談

0時に寝て7時に起きた。あまりよく眠れない。新しい施設のサービスインで社員さんは忙しそうなので画面のバグ修正をしたりレビューの検証をしたりしていた。

スクラムイベント

Scrum Developers Night! Online #11 に参加した。過去にストーリーポイント運用がうまくいってないという話題を書いてきたけど、他の組織やチームだとうまくいっているのか、どんな感じなのかを聞いてみようという意図で参加した。他のスクラムやっている人たちの話しを聞いてみたかったんだけど、割とこっちのやり方や運用を聞かれるような展開になったのでこちら側の話しが主になってしまった。相談してわかったことなどをざっくりまとめる。

  • ストーリーポイント運用の方法自体は間違っていない
    • ストーリーポイント運用とは別のところに課題があるようにみえる
  • スプリントで決めたことをできないのは問題
    • 1週間の見積もりすら合わないのだからそれ以上の期間の見積もりはあわないのは自明
  • プランニングやリファイメントなどでタスク分割や見積もりの精度をあげないといけない
    • 大きな機能の見積もり後にタスクが増えるような精度が問題
  • スプリントがある週の実稼働時間を考慮して見積もりしていないのは問題
    • 休みがあったり社内イベントがあったり実稼働時間によってベロシティはブレるはず

全体として総括すると、ストーリーポイント運用以前に、チームの問題が大きいのだろうと他の人たちと話していて実感した。スクラムの実践についての細かい改善点はあるものの、それ以上にチーム事情によるものや体制の問題の方が大きいということに気付いた。

レンダリングの致命的なバグ

0時に寝て6時に起きた。

vuejs のライフサイクル

先日 vuejs で 画面作り に挑戦して出来たと喜んでいたが、検索して一覧画面のデータを更新した際に、フォームも再レンダリングされないといけないところがそうなっておらず、データは置き換わっているが画面に表示される値は変わっていないという致命的なバグがあることに気付いた。普通に開発していたら気付きそうなものだが、ローカルの dev server で動かしているとコードを更新すると再レンダリングが実行されるので検索後に画面の一覧が更新されないということを見逃したんだと思う。Lifecycle Diagram もみながら適切なフックポイントの振る舞いを確認したりしていた。setup 後、初期化されてその後に mounted が動いて、その後パラメーターが更新されたときに watch して再更新をかけるといった次のコードでも意図した振る舞いになることは確認した。

  setup(props, context) {
    const data: { [key: string]: any } = {};
    return { _data: ref(data), loading: false };
  },
  mounted() {
    this._data = JSON.parse(this.item.data);
  },
  watch: {
    item(value: any) {
      this._data = JSON.parse(value.data);
    },
  },

レビューしてもらったら、それよりもパラメーターをリアクティブにした方がよいのではないかと教えてもらって次のようにした。本当は setter は不要なんだけど、なぜか初期化のタイミングで setter が呼ばれるので設けた。私の作ったコンポーネントの設計が悪いせいかもしれない。

  setup(props, context) {
    const _item = toRef(props, 'item');
    return { _item };
  },
  computed: {
   _data: {
     get(): { [key: string]: any } {
       return JSON.parse(this._item.data);
     },
     set(value: any) {
       this.$emit('update:_data', value);
     },
    },
  },

これは vue2 の Options API と呼ばれる記法で、vue3 だと Composition API を使って次のような書き方ができるというのも教えてもらった。getter だけなら Composition API でもよさそうだけど、setter もあるとこのコードはまったく簡潔じゃないなと思って Options API を使うことにした。

  setup(props, context) {
    const _item = toRef(props, 'item');
    const _data = computed({
      get: () => JSON.parse(_item.value.data),
      set: (value: any) => this.$emit('update:_data', value),
    });
    return { _item, _data };
  },