にゃみかんてっくろぐ

猫か百合を見守る壁になりたい

2023 年を振り返る

以前、はじめて転職活動をした際に「過去をしっかり振り返っておくことが大事」と言われたことがある。これに従って振り返る(過去分:2022年2021年2020年)。

技術的なもの

性能改善

気がつくと前職でも現職でも性能改善をやっている。広く浅くではあるけれど、「やりすぎず、よい匙加減で」「問題が起きる前に、予防的に」改善するのは結構難しい。

徐々に体系化できつつある感触もあり、 Zenn のスクラップに整理していこうと考えている(自己流 Web サービスの性能改善のすすめかた)。

P2P 地震情報

Windows 版はバージョンアップを 3 回、スマホ版は 2 回行った。

技術的だがお気持ちが強いもの

1 月に転職して約 1 年。

仕事: 答え合わせの 1 年、過去一番コードを書いた 1 年

今年の個人テーマは「答え合わせ」。これまで培ったスキルや価値観はどこまで活かせるのか、そもそも世の中で求められているものなのか。結論から言えば、「活かせるし、求められているし、まだまだのびしろがある」。

加えて、過去一番コードを書いた 1 年だったと思う。徐々にコーディング力が衰えていると認識していたため、技術スタックが大きく変わった状況にも関わらず「書けるじゃん」という安堵と嬉しさがあった。

仕事: 大いなる力には、大いなる責任が伴う

昨年はかなり悶々としていたが、転職して状況が変わった。いまのところすごくフィットしている。

  • 小規模なチームになった
  • 開発の裁量のほとんどを持つようになった
  • めちゃくちゃコードを書くようになった

ただし、大いなる力には、大いなる責任が伴う。言ったことはそのまま通ってしまうので、一言でプロダクトの成長を左右しかねない。

プロダクトの現状や今後を見つつ、短期的・中期的・長期的それぞれの目線で考えつつ、最適な手を考えて打っている。

技術的でないもの

重要伝統的建造物群保存地区

日本の町並み 250」という本で「(重要)伝統的建造物群保存地区」の存在を知り、町並み巡りが捗った。

ワーケーション

千葉で数日、盛岡では 1 週間過ごした。いい気分転換になるし、刺激にもなった。


おわり。

品質と工数をトレードオフにしない

ソフトウェアの外部品質を上げたい局面はいろんなところで発生する。不具合が発生した、障害が発生した、利用者が増えた… などなど。

このとき私がポリシーにしているのは、品質と工数トレードオフにしない、ということだ。

品質が上がるが、工数も増えるケース

例えば以下のような対策は、品質が上がる一方で工数も増えてしまう。

  • デプロイ前にチェックする手順を増やす
  • プルリクエストの承認(レビュアー)を 1 人から 2 人以上に増やす
  • 長時間の設計ミーティングに全員参加する

私はよく「開発プロセスが重たくなる」と表現している。

品質は上がるが、工数は変わらないケース

以下のような対策はどうだろうか。

  • スクリプトで自動的にチェックする
  • ESLint などの静的解析ツールを導入し、ツールに怒ってもらう
  • すぐロールバックできる仕組みを整え、影響範囲を小さくする

導入工数はかかるが、日々プロセスを回していく工数はほとんど変わらない。開発プロセスが重たくならずに、品質が上がる。

私が好きな対策だ。選択肢が限られていたり、導入工数がかかったりと難しい面もあるが、だからこそ取り組む価値もあると考えている。

怠惰であれ

表に整理するとこんな感じだろうか。

品質\工数 増える 変わらない 減る
上がる それはそう 💮 よい 💮 素晴らしい
変わらない よくない 今まで通り 💮 よい
下がる よくない よくない それはそう

もっと極端に言えば、「仕組みや自動化でなんとかなることを、わざわざ人の手でやりたくない」。そんな感じ。

2022 年を振り返る

以前、はじめて転職活動をした際に「過去をしっかり振り返っておくことが大事」と言われたことがある。これに従って、 2020 年2021 年と振り返っていたので、 2022 年も振り返る。

技術的なもの

新しいことにも手を出しつつ、 15 年以上続く P2P 地震情報の改善も継続して行った。

ISUCON 初参加(予選敗退)

Rust で DNS フルリゾルバ実装

P2P 地震情報

運用負荷軽減とパフォーマンス改善が中心。機能的には、緊急地震速報(警報)への対応が最も大きかった。

技術的でないもの

紅葉、雪見旅

東北~近畿地方を巡った。川瀬巴水「平泉金色堂」(絶筆)と同じ、雪がしんしんと降る中尊寺 金色堂は本当に良かった。

PC192710_DxO

たいぷらいた~’s albums | Flickr

アプリの MAU を増やす

あるきっかけで、 P2P 地震情報の MAU を増やす工夫をいくつかやった。因果関係があるか分からないが、微増はしている。

P2P 地震情報 モバイルの MAU, WAU, DAU

技術的だがお気持ちが強いもの

より適したソフトウェアアーキテクチャを探る

ずっと KKD (勘と経験と度胸)に頼っていたが、仕事ではもうちょっと真面目にやりたくて試行錯誤した。効果があったなと感じているのは 2 つ。

1 つは、 Design It! の第 II 部 5 章「アーキテクチャ上重要な要求を掘り下げる」にある「アーキテクチャ上重要な要求 (Architecturally Significant Requirement: ASR)」の 4 分類。

  • 制約
  • 品質特性
  • 影響を与える機能要求
  • その他の影響を及ぼすもの

Michael Keeling; 島田 浩二. Design It! プログラマーのためのアーキテクティング入門 (Kindle の位置 No.1524-1526). 株式会社オライリー・ジャパン.

もう 1 つは、 Clean Architecture 第 15 章「アーキテクチャとは?」にあるこの一文。

ソフトウェアをソフトに保つには、できるだけ長い期間、できるだけ多く選択肢を残すことである。では、「残すべき選択肢」とは何だろうか? それは、重要ではない詳細である。
(略)
また、決定を遅延できれば、その分だけ適切に作るための情報が数多く手に入る

Robert C. Martin; 角 征典; 高木 正弘. Clean Architecture 達人に学ぶソフトウェアの構造と設計 (アスキードワンゴ) (Kindle の位置 No.2263-2265, No.2285-2286). 株式会社ドワンゴ. Kindle 版.

詳細はそれぞれ書籍を参照されたい。

この実践は、他人に説明しやすいというメリットもあった。一方、選択肢をどれだけ出せるかについては KKD (勘と経験と度胸)でやってしまっている。 2023 年の課題になるだろうか。

技術へのリスペクト

技術へのリスペクトがなくてもプロダクトやビジネスは成功するかもしれない。ただ、選択肢があるなら、技術へのリスペクトがある組織にいたい。ここ 1 年というより 2 年くらい感じていたことだった。


おわり。

デプロイ頻度を上げるための「下準備」

デプロイ頻度を上げた話ではなく、デプロイ頻度を上げるために必要なことを洗い出して実施したという話。

月 1 回のビッグバンリリース

所属チームは月 1 回のいわゆるビッグバンリリースで、まあ大変な状況だった。

  • デプロイ作業は 2 時間超
  • 500 ファイル以上の変更
    • 不具合発生時の原因特定が困難
    • 「原因以外の変更を取り消したくない」ため、ロールバックは原則行わず MTTR が長い
  • 「今月のリリースに間に合わせたい」ための行動が起きがち

Four Keys の話もあるし、列挙したチームの状況を鑑みても、デプロイ頻度を上げる価値はあると考えた。

いきなり毎日デプロイできるか? いいえ。

じゃあ月 1 回だったデプロイをいきなり毎日できるかというと、現実的ではない。今よりも大変になってしまうし、そもそも毎日デプロイするものもない。そんな状態で毎日デプロイしても価値は出ない。

まずは、デプロイ頻度を上げるための土台づくりが必要になってくる。 Four Keys はよくできているな… と感じる。

土台づくり

では、土台づくりで何をするか。ここの掘り下げは yigarashi さんの Four Keysがなぜ重要なのか - 開発チームのパフォーマンスを改善する方法について - yigarashiのブログ30分でわかるFour Keysの基礎と重要性 - Speaker Deck をめちゃくちゃ参考にした。その上で、チームの状況を見ながら以下の取り組みを行った。

  • プルリクエストを小さくする
  • すばやくレビューする
  • テストコードがない箇所は書く
  • カナリアデプロイを可能にする
  • 素早いロールバックを可能にする
  • デプロイ作業を軽くする

プルリクエストを小さくする

デプロイ頻度を高めるには、デプロイする「モノ」を高頻度に生み出す必要がある。そのためには、プルリクエストを小さく分割し、高頻度にマージできるサイズになっていると良いはずだ。

チームでは、 Google Engineering Practices のコードレビューガイドラインを取り入れつつ、変更は最大でも 300 行以内という基準を設けた。

元々はコードレビューの遅さが嫌になって始めたものだが、巡り巡ってデプロイ頻度改善の下地にもなっている。

すばやくレビューする

チームではレビューを必須としているため、デプロイの高頻度化には素早いレビューも欠かせない。

これも Google Engineering Practices のガイドラインに従って 1 営業日以内のレビュー(またはレビュアー代打の提案)を行うようにした。また、別チームが開発したレビューリマインダー Bot を活用して、 1 日数回リマインドするようにした。

テストコードがない箇所は書く

例えばリファクタリングなら、 API の入出力が変化していないことを検証しておくと良い。シンプルに書くだけである。

一見、デプロイ頻度と無関係に思える。しかし、「高頻度にデプロイして大丈夫なんですか?」という不安に対する答えを用意しておくことは、意外と重要だと感じる。

カナリアデプロイを可能にする

万が一問題が発生したときの影響範囲を、可能な限り小さくしておく。

これもデプロイ頻度に直接作用するものではなく、不安を和らげる策の 1 つである。

素早いロールバックを可能にする

万が一問題が発生したときに、速やかに元に戻せるようにしておく。

これもやはり、高頻度なデプロイに対する不安を緩和するためのものである。

デプロイ作業を軽くする

これはデプロイ頻度に作用する。単純作業は自動化してしまえば良い。

ただ、チームには自動化までの道のりが長いプロセスもあった。具体的には、 QA (品質保証)と、受託開発でいう「受け入れテスト」相当のプロセス。

これについては、リファクタリングに限り、プロセスを思い切って省略することにした。

本来省略すべきものではないが、「事前に議論しても、リスクを取る選択はしづらいのでは」「一度やってみたデータがあるほうが、議論しやすいのでは」と考えた結果である。

試せる土台は整った

ここまでで、試しにデプロイ頻度を上げても良いと感じる程度には、土台は整ったと思う。

ひとり毎日デプロイ

単独で行っているリファクタリングのプロジェクトだけ、短期間毎日デプロイを試した。

思った以上に何も起こらなかった。

一度だけ不具合を起こしたが、原因を深掘りすると、従来のビッグバンリリースでも起きうる内容。カナリアリリースや素早いロールバックがプラスに働きそうだ。

あとはチーム次第

今後チームとしてデプロイ頻度が上がるかは、チーム次第。諸々の事情で遠巻きから見守ることになったので、本当にチーム次第である。

仮にデプロイ頻度が変わらなくても、それぞれの土台づくりが全く無駄になるわけではない。より高品質で、より安全なデプロイの一助になっているはずだ。

参考資料

毎日 1000 万リクエストを捌く 1 台の API サーバー

P2P地震情報API サーバー (api.p2pquake.net) は、毎日 1000 万リクエスト以上を捌いている。ピーク時は毎秒 300 リクエストを超える。

VPS 1 台でここまで到達するのにそこそこ試行錯誤した。結果として意外性はなくやることやっただけという感じではあるのだが、アーキテクチャーや設定値を整理して記事にしておく。

前提となる構成、及び状況

  • Linode Dedicated 4GB プラン x 1 台
    • CPU: AMD EPYC 7601 32-Core Processor 2 コア (専有)
  • 公開 API は GET (読み取り) のみ
    • 書き込みは地震情報・津波予報の発表時などに限定

Nginx, Go + Gin, MongoDB の 3 層構造

DB: MongoDB Capped Collections

DB はドキュメント指向データベースである MongoDB を使用していて、 API のレスポンスほぼそのままの形でデータを格納している。 2015 年頃から運用中(それ以前は CSV ファイルベース)。

> db.whole.find({ code: 551 }).sort({ $natural: -1 }).limit(1)
{ "_id" : ObjectId("63244a1551d38bb17b2e7c91"), "issue" : { "time" : "2022/09/16 19:04:04", "type" : "DetailScale", "correct" : "None", "source" : "気象庁" }, "timestamp" : { "convert" : "2022/09/16 19:04:05.177", "register" : "2022/09/16 19:04:05.204" }, "user_agent" : "jmaxml-seis-parser-go, relay, register-api", "ver" : "20220813", "earthquake" : { "foreignTsunami" : "Unknown", "time" : "2022/09/16 19:00:00", "hypocenter" : { "name" : "東京湾", "latitude" : 35.5, "longitude" : 140, "depth" : 20, "magnitude" : 2.5 }, "maxScale" : 10, "domesticTsunami" : "None" }, "points" : [ { "pref" : "千葉県", "addr" : "市原市姉崎", "scale" : 10, "isArea" : false } ], "code" : 551, "time" : "2022/09/16 19:04:05.204" }

最大の特徴は Capped Collections を使用していること。これはリングバッファー相当のもので、コレクションを一定サイズに保つことができ、古いドキュメントは自動的に消えていく(上書きされる)。直近の情報を提供できればよいP2P地震情報にぴったり合う。

ストレージエンジン WiredTiger のキャッシュは最小の 256 MB 。

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
systemd+    1750 11.9  9.1 2210568 366816 ?      Ssl  Jul09 10836:08 mongod --wiredTigerCacheSizeGB=0.25 --auth --bind_ip_all

速度

速い。

P2P地震情報では 32 MB の小さな Capped Collection で運用していて、直近 10 件の地震情報を探す時間は 1 ms くらい。

> db.whole.stats()
{
        "ns" : "p2pquake.whole",
        "size" : 33553274,
        "count" : 12057,
        "avgObjSize" : 2782,
        "storageSize" : 8462336,
        "freeStorageSize" : 2072576,
        "capped" : true
        (略)
}
> db.whole.find({ code: 551 }).sort({ $natural: -1 }).limit(10).explain("executionStats")["executionStats"]["executionTimeMillis"]
1
> db.whole.find({ code: 551 }).sort({ $natural: -1 }).limit(10).explain("executionStats")["executionStats"]["executionTimeMillis"]
0

Tailable Cursors

Capped Collections を使うメリットはもう 1 つあって、それが Tailable Cursors 。これは tail -f 相当で、簡易的な Pub/Sub として使える。

プッシュ通知、 WebSocket API 配信などで活用している。厳密には計測していないが、レイテンシは 1 ms あるかないか程度。

アプリケーションサーバー: Go

もともと Ruby + Sinatra だったが、新しい API については Go + Gin で作っている。古い API も徐々に Go + Gin に移行したい。

[GIN] 2022/09/10 - 08:42:13 | 200 | 2.064529ms | xx.xxx.xxx.xxx | GET "/v2/history?codes=551"
[GIN] 2022/09/10 - 08:42:14 | 200 | 19.144558ms | xx.xxx.xxx.xxx | GET "/v2/history?codes=551&limit=40"

Web サーバー: Nginx

アプリケーションサーバーへのリクエストをとにかく減らす ため、キャッシュ設定を諸々行っている。

proxy_cache_lock イメージ. アプリケーションサーバへのリクエストは 1 つだけ

server ブロック抜粋:

proxy_cache_use_stale timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
proxy_cache_lock_timeout 30s;
proxy_cache_valid 200 1s;
proxy_cache_valid 302 1h;
proxy_connect_timeout 5s;

proxy_next_upstream error timeout http_504 http_502;

location /v2/ {
    limit_req zone=apiv2 burst=10;
    proxy_cache cache;
    proxy_pass http://127.0.0.1:10001;
}
location /v2/jma {
    limit_req zone=apiv2jma burst=10;
    proxy_cache cache;
    proxy_cache_valid 200 10s;
    proxy_pass http://127.0.0.1:10001;
}

Nginx に 142 requests/s 来ているが、 アプリケーションサーバーに到達しているのはわずか 6% の 8.13 requests/s である。

あとはファイルディスクリプタ数の上限worker_connections を引き上げたり、 net.ipv4.tcp_tw_reuse を 1 にしたり、くらい。

課題

TLS の負荷(たぶん)

諸々の結果、いま最も CPU リソースを消費しているのは Nginx になっている。

HTTPS ではなく HTTP でベンチマークを流すとこんな負荷は掛からないので、 TLS の負荷だと推測している。

top - 11:40:50 up 63 days, 15:47,  1 user,  load average: 0.42, 0.84, 1.05
Tasks: 247 total,   2 running, 245 sleeping,   0 stopped,   0 zombie
%Cpu(s): 15.2 us, 14.3 sy,  0.0 ni, 68.0 id,  0.0 wa,  0.0 hi,  2.5 si,  0.0 st
MiB Mem :   3931.3 total,    358.7 free,   2375.9 used,   1196.6 buff/cache
MiB Swap:   4608.0 total,   3882.1 free,    725.9 used.   1208.3 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
1676684 systemd+  20   0  163092  79328  32748 S  12.5   2.0 496:19.37 nginx: worker process
   1750 systemd+  20   0 2210568 379080  10656 S   8.2   9.4  10913:42 mongod --wiredTigerCacheSizeGB=0.25 --auth --bind_ip_all
2802253 root      20   0  749316  67716   9608 S   5.2   1.7   3185:14 /usr/bin/cadvisor -logtostderr --global_housekeeping_interval=5m0s --housekeeping_in+
    524 root      20   0 2640424 151960  18512 S   3.8   3.8   3667:06 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
2243005 root      20   0  721888  26240  14152 S   2.7   0.7  25:08.70 ./web-api-v2
2242527 root      20   0  721056  28592  14348 S   1.9   0.7  25:02.20 ./web-api-v2

今後負荷が問題になってきたら、 ECDSA 証明書を試すか、 Load Balancer に TLS を終端してもらうかで考えている。

数百万件残っていたHTTPのはてなブログを4年越しにすべてHTTPS化させた話 - Hatena Developer Blog

最後に

まだまだ IPv4 アクセスが多い。

CPU, Disk I/O, Network I/O の状況. CPU は Max 200% であることに注意

www.p2pquake.net のサービスをぜんぶ Docker でコンテナ化した(計 35 コンテナ)

※個人開発の備忘録です。

Debian 9 (stretch) が EOL を迎えたので、ちょうど良い機会だと思って色々と手を加えた。

  • Debian 11 (bullseye) に
  • すべてを Docker でコンテナ化
  • 監視ツールを Munin + Xymon から Prometheus + Grafana に
  • Vultr から Linode

すべてを Docker でコンテナ化

www.p2pquake.net は VPS 上で動いていて、小さなサービスの組み合わせで P2P 地震情報が成り立っている。

P2P 地震情報のサービス構成図

が、「まぁ動いてるからヨシ!」状態で、以下のようなサービスもある。

  • インスタンス再起動後に手で起動している
  • ずっと安定稼働して、セットアップ方法がわからなくなっている

サービスの起動し忘れで不具合が起きたりもしていた。

そこで、その辺の問題を解消すべく、重い腰を上げてすべてコンテナ化した。

Dockerfile が 500 行ちょっと、 compose.yml が 800 行ちょっと。ちゃんと (?) Docker Compose V2 を使っている。

~/production (master) $ find epsp-server-apps/ epsp-web-services/ -name Dockerfile | xargs -I{} wc -l {} | cut -d" " -f1 | awk '{s += $1} END {print s}'
530
~/production (master) $ find epsp-server-apps/ epsp-web-services/ -name compose.yml | xargs -I{} wc -l {} | cut -d" " -f1 | awk '{s += $1} END {print s}'
807

ただの MongoDB や Blue/Green デプロイ用に多重起動しているものもあるけれど、計 35 コンテナが動作している。

NAMES                                         STATUS
external-fluent_push-1                        Up 4 hours
external-fluent_twitter-1                     Up 4 hours
external-api-1                                Up 4 hours
server-areapeer-deliver-1                     Up 23 hours
epsp-web-services-eew-gateway-1               Up 23 hours
epsp-web-services-mobile_bridge-1             Up 23 hours
epsp-web-services-client-1                    Up 23 hours
server-client-1                               Up 23 hours
server-server-1                               Up 23 hours
jma_collector-broadcaster-1                   Up 24 hours
jma_collector-client-1                        Up 24 hours
epsp-web-services-https-portal-1              Up 2 days
epsp-web-services-static-1                    Up 2 days
epsp-web-services-realtime-api-green-1        Up 2 days
epsp-web-services-realtime-api-blue-1         Up 2 days
epsp-web-services-web-api-green_www-1         Up 2 days
epsp-web-services-web-api-blue_www-1          Up 2 days
epsp-web-services-web-api-v2-green-1          Up 2 days
epsp-web-services-web-api-v2-blue-1           Up 2 days
epsp-web-services-web-api-blue_backend-1      Up 2 days
epsp-web-services-web-api-green_backend-1     Up 2 days
server-metrics-1                              Up 2 days
jma_collector-dmdata_connector-1              Up 2 days
jma_collector-register-1                      Up 2 days
jma_collector-jma_watcher-1                   Up 2 days
epsp-web-services-traefik-1                   Up 2 days
epsp-web-services-prometheus_exporter-1       Up 2 days
userquake_aggregator-userquake-aggregator-1   Up 2 days
replicator-replicator-1                       Up 2 days
logger-logger-1                               Up 29 hours
logger-register-1                             Up 2 days
instance-exporter-cadvisor-1                  Up 2 days (healthy)
instance-exporter-node-exporter-1             Up 2 days
mongodb-mongodb_exporter-1                    Up 2 days
mongodb-mongodb-1                             Up 2 days

監視ツールを Prometheus + Grafana に

これまで Munin と Xymon を組み合わせてやってきたが、さすがに厳しい気がして Prometheus + Grafana に移行した。

Munin: MongoDB のメトリクス

Grafana: MongoDB のメトリクス

Munin は有志の手によって様々な plugin が作られてメトリクスが収集できていたけれど、 Prometheus も同じように様々な exporter でメトリクスが収集できた。

Traefik は標準で Prometheus サポートが入っているし、比較的モダンなソフトウェアとモダンな監視ツールの相性はやはり良いのかなという印象(個人の感想です)。

Linode

さくらの VPS から Vultr を経て、 Linode の Dedicated CPU インスタンスに移行した。 CPU 専有。

というのも、 CPU リソースを割と消費していて、「これ高負荷を理由に止められてもおかしくないのでは…」という心配が常にあったからである。

CPU 専有ならその心配はない(はず)。

RAM 4 GB, 2 vCPU で月 30 ドル。 Shared CPU だと月 20 ドルで、月 10 ドルの上乗せで済んでいるなら良いかなという気持ち。

Grafana: CPU 使用率は 40% 弱

Amazon Lightsail も考えたが、この CPU 使用率だと月 80 ドルのインスタンスタイプが必要になるため断念した。


そんなこんなで色々とモダンになり、省力化ができましたとさ。めでたしめでたし。

2021 年を振り返る

以前、はじめて転職活動をした際に「過去をしっかり振り返っておくことが大事」と言われたことがある。これに従って 2020 年を振り返っていたので、 2021 年も少し遅いけれど振り返っておく。

技術的なもの

個人開発: フロントエンドから OS 自作まで

主なものを整理するとこうなる。量は多くないが、普段あまり触らない領域に手を出せたのは良かった。

種類 名前 言語・フレームワーク
Web サービス メリうた🐝 TypeScript, React, Ruby
P2P 地震情報 スマホ版リニューアル
Windows 版リニューアル
Dart, Flutter
C#, WPF
OS ゼロからのOS自作入門 C++

やっとフロントエンドの感覚がつかめた

メリうた🐝 の開発当時のツイート。 jQuery でずっと止まっていたフロントエンドの知識をかなりアップデートできた。

これまで、いわゆる SPA にはユーザ体験向上のイメージしかなかった。いざ触ってみると、設計・実装が宣言的 UI やコンポーネント化で整理されるのがとても良いと感じた。

はじめての Flutter

P2P 地震情報のスマートフォンアプリ。 iOS 版は機能が貧弱、 Android 版は UI が古い… ということで Dart, Flutter でリニューアルを実施した。

「Flutter のために Dart を…?」と思っていたが、そんなに癖はなく書きやすかった。それよりも、プラットフォーム間の差異がしっかり吸収されていること、ドキュメントが大変充実していることに驚くばかりだった。

リニューアル後はかなりエゴサをしていたが、好評で嬉しかった。私自身もずっと使っている。

10 年越しのソフトウェアリニューアル

P2P 地震情報のスマホアプリを 2 年ぶりにリニューアルした後、 Windows 版を 10 年ぶりにリニューアルした。 C# (.NET 5), WPF で、コアとなる P2P 通信部分はクロスプラットフォームGUIWindows のみで動作する。詳細は以下に記している。

Linux, macOS にも対応させたい気持ちはあるが、各プラットフォーム毎に作ってメンテナンスできる自信がない。 .NET MAUI に期待している。

OS 自作

ゼロからのOS自作入門」(みかん本)。 Twitter で見かけて絶好のタイミングだと思って始めた。

コンテキストスイッチの実装はめちゃくちゃテンションが上がった。はるか昔、パソコン用語事典かなにかでプリエンプティブマルチタスクを知り、大学生あたりで切替方法を知り、とうとう実装することになり… という具合。

本に抜粋されているコード以外は推測するスタイルで、理解が足りず頻繁にバグっている。 30 日でできるはずが半年経ってまだ 17 日分。でも楽しい。

技術的であるがお気持ちが強いもの

仕事

主にテックリードっぽいことをしていたが、正直かなり悩みの多い 1 年だった。

誤解を恐れずに言えば、私が苦手とする「技術のわからないリーダー」に私自身がなってしまうのでは、という焦燥感と恐怖があった。

また、振る舞いや判断が良かったのか悪かったのか、よく分からなかった。定量的な数値を追うべきだったかもしれないが、数値が変化したとてテックリードの成果と言えるのだろうか。

はっきり良かったと思っているのは、 Google Engineering Practices によるコードレビューの高速化、リーダブルコード輪読会の 2 点(テックリード 1 年半、試行錯誤の断片 - にゃみかんてっくろぐ)。ただし、チームメンバーに恵まれていてタイミングが良かっただけで、私自身の成果とは言い難い。

技術的でないもの

京都(紅葉)

流行り病のケース数が落ち着いていた頃、 2 年ぶりに京都へ行った。最高だった。

いつも見頃前に訪れることが多かったが、今回は見頃やや過ぎ。しかし、散った紅葉も大変に美しかった。

創作意欲、クリエイターへの憧れ

何かを生み出すのは尊いし、憧れる。個人開発もある種の創作活動だと思っている。このときのツイートは、メリッサ・キンレンカさんや OSTER project さんの配信を見てのものだと思う。

おわりに

2020 年と同様、計画的偶発性理論に従って、良い方向に進むよう日々積み重ねていく。めでたしめでたし。