Posts for: #Refactoring

コンテキストによるキャンセル処理

1時に寝て7時に起きた。昨日がっつりコードを書いていたせいか、起きてから今日は休みたいと思いながらだらだらしてた。休めないのだけど。貧乏暇なし。

echo のリクエストコンテキスト

昨日の続きで mongodb のリファクタリングをしている。mongodb はほぼすべての処理で コンテキスト を受け取れるように設計されている。メンバーが go の context の扱いを理解していないのでコンテキストを渡すようなインターフェースになっていない。私もこれまでのコードレビューでキャンセル処理は些事なのでそれよりも機能開発を優先して後回しにしていた。それで、いま機能が一通り開発完了したのでインターフェースにコンテキストを受け取るようにリファクタリングした。デフォルトのコンテキストとして echo のリクエストコンテキストを渡す。Canceling request #1815 によると、echo のリクエストコンテキストは次の状況のときにキャンセルしてくれる。

  • クライアントのコネクションがクローズされたとき
  • http2 でリクエストがキャンセルされたとき
  • ServeHTTP() が返るとき
    • サーバーがシャットダウンするタイミング?

使い方はこんなイメージ。

ctx := c.Request().Context()
store := c.Get(myStore).(Store)
store.Get(ctx, request.From, request.To)

mongodb の view 調査

4時半に寝て11時に起きた。午後から go のコードをリファクタリングしてた。平日はメンバーの issue を監視して困ってたらコメントしたり、マージリクエストをレビューしたり、管理画面の振る舞いを検証したりと、コードを書いていても途中で作業がちょくちょく中断する。休日にコードを書くとその中断がない分、いつもよりかなり捗った。リファクタリングに思いの外、時間を取られている気がしたのはそのせいもあるか。

mongodb の view 作成

実はこれまで mongodb を扱ったことがなくて今回初めて触っている。とくに難しくもないのだけど、ドキュメントを探してやりたいことを調べたり、デバッグや開発のためのツールとしてどういうものがあるかといった知見がない。ないものは仕方ないので1からドキュメントを読みながら開発というか、リファクタリングをしている。mongodb そのものの知見はなくても、様々なデータベースを操作する開発をしてきたのでやりたいことに対して実装方法はいくつか検討がつくし、その実装を支援するための機能もあるはずだと予測がつくので探すのも早い。

ある collection から複数のデータ構造のレスポンスを返すような処理がある。こういったものは view を使うとうまく整理できると知っているので調べると mongodb view が提供されていることがわかる。3.4 から追加されたらしい。いまクエリの中で aggregation pipeline を書いている処理のいくつかは、あらかじめ view を定義してクエリすることでインフラ層を堅牢にした上で実装もシンプルにできる。さらに 4.2 から on-demand materialized view が追加されていて、標準の view と比較して aggregation pipeline の計算結果をディスクに保持するのでパフォーマンス上のメリットがある。元データの更新が頻繁でなければ on-demand を使った方がよいのだろうと推測する。

またこれまで mongodb の管理画面に mongo-express を使っている。view の振る舞いを確認しようとしたところ、どうも view には対応していないようにみえる。web ベースの管理画面を他にも探してみたが、どうも他に適当なものがない。mongodb が公式に compass というデスクトップアプリケーションの gui クライアントを提供している。macos なら brew からインストールできた。

> brew install mongodb-compass

このツールは collection も view も両方扱えるし、クエリやパイプラインも実行できて機能も充実している。web ベースじゃないとインフラとして共有はできないところだけが残念なところ。それでも開発する上ではとても強力なツールにみえる。適当にデータをインポートしたり、テストで aggregation pipeline を作成してみて、それをエクスポートして view を生成するときのスキーマ定義も作ることができた。ui も洗練していて、こんな優れたデスクトップアプリケーションは久しぶりにみたと思うぐらい感心した。

mongodb を触ってみる

0時に寝て7時半に起きた。今日は1日中リファクタリングしてコードを書いていた。

リファクタリング

mongodb 周りのインフラ層のリファクタリングしている。過去に mongodb を触ったことがなかったので mongodb そのものの振る舞いや仕様なども理解しながらリファクタリングしている。その第一弾として差分が1500行以上のマージリクエストを作った。私の中ではまだ 1/3 ぐらいの進捗。動くレベルになったのでコードレビューを通じてメンバーと設計の考え方を共有していく。差分は多いけど、重要なところは一部だけ。やり過ぎだなと思えるのは、設計を見直すとテストコードを書き換える必要があって、その書き換えをやっていると時間が削られる。設計の部分だけ変更して、その後の作業をメンバーに引き継いでもらうといったやり方ならもっと早くできるかもしれないけど、テストコードを書き換える過程で私もユーザーの立場になって設計の良し悪しを検証するきっかけになるのでこの作業は自分でやることにも価値があると考えている。

設計がよくないところをどうやってメンバーに指導していくかはなかなか難しい。良し悪しは複数の設計を比較することで初めて気づくことも多い。私はその引き出しが多いので比較対象がたくさんあるだけでメンバーはその引き出しが少ないから悪い設計と認識できないでいる。その比較対象を私が提示してメンバーが考える機会にしてあげたい。理屈上はこれだけなんだけど、現実のコードと納期とのバランスを取るのが難しい。

いい加減マネージャーがリファクタリングに工数を使い過ぎだろうと私自身でも思うようになってきたので週末に残りのコードを書いて区切りのよいところでひと段落つけようと思う。

個人の人生と会社の経営

1時に寝て6時半に起きた。久しぶりに起きずに長時間眠れた気がする。1-2ヶ月に1回あるかどうかぐらいの感覚。

リファクタリング

ここ最近、私がバックエンドのリファクタリングを集中的にやっている。私からみたらバックエンドの設計にはいくつか改善の余地がある。動いているという視点では及第点ではあるし、メンバーは限られた時間の中で十分にうまく開発していると考えている。それでも、遊撃として余裕があるときにリファクタリングをしている。これから運用レベルの QA テストに入っていく。その前にがーっとリファクタリングしておくとテストで振る舞いを検証できるし、テストで別の不具合をみつけたときも保守コストが下がるように設計を洗練させておくことには一考の価値がある。実際にコードを書き始めると時間をどんどん取られて、マネジメントの業務から離れていってしまう。マネージャーがコードに集中し過ぎるのも問題だというのも理解できるようになってきた。本来はあまり深入りしない程度にメンバーに要点を伝えて改善したもらうのが正しいとは思う。いろいろプロジェクトの都合があるので必ずしも思い描いたようにはいかない。バランスをとってうまくやりたい。

余暇と経営と個人

1月以降は実家の法事のために私の余暇の半分程度の時間を取られている。先週末に49日を終えたので次の法事は初盆まで余裕がある。とはいえ、弁護士さんと実家と相続のやり取りがあってまだ何割か時間を取られている。この余暇の時間に、これまでは自社の業務や事務手続きをしている。その余暇が少なくなると、最終的には他のところにも皺寄せがいく。余暇に余裕がないと自分の会社を経営するのはなかなかしんどいところもあるかもしれない。

来季は実家の一部を自社のオフィスにしようと考えている。よくよく考えれば、神戸のオフィスでフルリモートワークをするのも、淡路島のオフィスでフルリモートワークをするのも、お客さんからみたら全く違いがない。いままでそうしてこなかったのは、神戸のオフィスでは業務に集中できるよう、私にとって最適な環境を構築し続けているからと言える。最も大きな違いは椅子だと思う。よい椅子でデスクワークしていると、あまり粗末な椅子でデスクワークしたくないというネガティブなモチベーションになってしまう。

メインオフィスと同じとはいかなくても準ずる程度のオフィス環境を実家に構築できれば実家に帰って1-2週間程度のフルリモートワークをしてもよいと考えている。その延長上で実家との行き来を出張扱いにして経費を使えるようにし、経営的にはそうすることで節税にもつながる。私個人の視点からも、親の介護という、私の人生設計上避けられない問題に対する解決策となる。個人の人生の問題と会社の経営を両立させることは、自分の会社であれば、十分に両立できると自信をもって言える。この話しも田舎から上京してその後のキャリアを考える上でのモデルケースの1つとして、いつかブログの記事として書きたい。

意図がわかる設計とリファクタリング

1時に寝て7時に起きた。久しぶりに HELLSING をみてた。アレクサンド・アンデルセンの狂信者ノリが好き。

煩雑な保守

昨日から着手した s3 とやり取りするアプリケーションの保守をしている。一通り機能は実装できたが、このアプリケーションの保守を今後どうやっていけばいいのかが私からはみえない。要件が変わる度に継ぎ接ぎで拡張してきて、意図をもった設計があるわけではないようにみえる。このまま保守することはできるかもしれないが、このロジックの説明もテストも検証もすべてが難しい。私がみても難しいのだから、経験の浅い開発者がみるともっと難しいのではないかと思う。

これを直すにはまず単体テストを直さないといけない。単体テストの大半がモックベースなので実際の振る舞いと異なる可能性がある。とくに s3 とやり取りするところの検証ができない。testcontainers の localstack があるので単体テストはモックからこのモジュールを使うように代替できそう。まずはそこからやるべきだが、2-3日はかかると見込まれるのでチームで承認を得られるかどうか、ちょっと聞いてみてから考える。

Job Summary を使ってみた

ちょっと前に github actions のワークフローの実行画面にサマリを出力できるようになったという記事をみた。

自動でよさげなサマリを出力してくれるわけではなく、自分でサマリを作らないといけないので面倒だなと思ってそのまま放置していた。先週末に モジュール別のビルド・デプロイのワークフロー改善 を行った。ふとワークフローの実行結果をみていて、選択したモジュール名が表示されているとわかりやすくていいなと思えた。それを出力する手段としてサマリがちょうどいいやということに気付いた。inputs などで動的に変更するパラメーターをワークフローの実行画面で確認できるといちいちログ確認する手間が省けてよいという場面が他の用途でもある気がしてきた。もっと積極的にサマリを使っていこうと思えた瞬間だった。

リファクタリングとオブジェクト指向プログラミング

0時に寝て8時に起きた。先週末の疲れが溜まってバテバテ。直近の1週間で睡眠時間が短いときは3-4時間しか寝てないのでなんか朝起きれなくて調子悪いなと思ったら単純に睡眠不足よね。なんか安心した。

既存ロジックのリファクタリング

ちょっと前にタイムラインで「値オブジェクト」の定義の話題で盛り上がっていた。私は詳しくないのでどちらが正しいのかの白黒を付けられないが、値オブジェクトがどういうものかの定義を知らなくても、オブジェクト指向プログラミングとしてデータ + メソッドでカプセル化していくモジュールの概念からすると普通のことであって、それの特殊ケースに名前が付いている・付いていないという議論だったのではないかと思う。

今日たまたま既存のある処理に機能を拡張するため、既存のコードを読んでいて、ロジックを扱うコンポーネントが肥大化していて、ここに手を入れていくとさらにコードの見通しが悪くなるように思えた。そのロジックコンポーネントの半分は出力用の DTO を生成する処理が占めていて、DTO を生成する処理をオブジェクトとして切り出すことでロジックコンポーネントを半分に分割できることに気付いた。パラメーターとして7つの値をそのオブジェクトの入力として、そのオブジェクトの内部であれこれやって、最終的に必要な DTO を出力できればよい。1つのコンポーネントを2つのコンポーネントに分割したことで、それぞれのコンポーネントのスコープにおけるメソッドが半分になったというだけの話し。一般的なカプセル化の話し。難しい話しをしなくても設計やオブジェクト指向プログラミングの基本的な考え方などをメンバーに教えていければいいんだけど、私はあくまで協力会社のお手伝いなので、教える業務は担っていない。次の契約更新のときにインフラやプログラミングを経験の浅い人たちに教えましょうか?みたいな話しもしたいと考えている。

java のコードレビューサービス

22時に寝て0時に起きて5時に起きて7時に起きた。なんか体調が微妙。

リファクタリングのチケット作成

これまでは業務に関係しないところの機能拡張をしていたので新規にコードを書くことが多かった。いま業務の開発にも着手し始め、その過程で既存のコードを読むことも多くなった。私からみたらコードの品質が著しく低くて、ただ動いているだけで堅牢でもないし、設計の意図も伝わらないコードが多い。そういうのを自分が変更するときに少しずつ出来る範囲でリファクタリングしたりしている。今日もコードを読んでいて enum の扱いについてチケットを作成した。

前に手伝っていた会社の契約を終了するときに java のコードレビューだけなんらかの契約で依頼できないかという話しはあった。そのときは別件のお仕事が火の車だったので断ってしまった。いまお手伝いしている java のコードをみても、java に慣れていない開発者の書く java のコードはたいていひどい。なぜひどくなるかというと、java は言語仕様が複雑で難しいからだと思う。java の経験が少ないと Effective Java を読んでも理解できないぐらいには java の設計は難しい。その結果として java で開発しているのに設計を練っておらず「動けばいい」コードが散見される。java で開発するなら「これ以外に動かない」コードを書いた方がよいと私は考えている。その意図が伝わるからドキュメントなんか読まなくても「動かすにはこう書けばいい」とわかる。さらにインターフェースが明確であれば、責務や拡張方法も明示的になる。

前から考えてはいたけど、sier や内製始めたばかりの事業会社向けに java のコードレビューのサービスを提供することも考えている。私1人だとたくさん受けられないし、コードレビューサービスのようなものは会社の信頼関係の方が重要なのでビジネスにするのはちょっと難しいかもなぁ。

見積もりのまとめ

先日 見積もりについて考察した 。もともとは社内向けに書こうと書き始めたが、内容の大半は社内に閉じたものではなかったので一般論の記事として書き直した。最終的には1万文字ぐらい書いた。

リリース作業の改善

1時に寝て6時前には起きてた。昨日がんばったから今日は早めにお仕事を切り上げた。

リリース作業を柔軟に、効率的に

以前から認識していた開発の課題にリリース作業のコストが大きいことがあった。具体的には人間が手動で進捗をみながら処理を実行していて、さらに1つずつの処理に数分かかるので順番に実行していくだけでも確認を含めて30分から1時間ぐらいかかる。リリース後に変更したところの動作確認とかを開発者が集まってやってたらだいたい2-3時間はかかる。だらだら?やっているとリリース作業に開発者全員がハドルに入って半日ぐらいやってたりする。最初のうちは雑談しながらリリース作業のやり方がわかってよかったんだけど、何度か繰り返したらこれを毎週やるのは非効率だわと思うようにはなっていた。

そんな開発側の事情もあったんだけど、スクラムマスターからもいまのリリース作業は柔軟性がないみたいな指摘が入って、その改善のチケットが切られた。開発者も全員それは認識していた。改善するならスプリントを1つ使うぐらいの工数がかかるという背景を説明するために、私が「ぼくのかんがえたさいきょうのりりーすさぎょう」を考えていくつかのタスクをチケットに作った。いま GitHub Actions の無料枠におさまるようにリソース制限を運用で調整しているのもあって予算確保できるなら戦略も変わってくる。それらも含めて然るべき改善の道筋を示したい。