壁打ちとシャトル

今日のバドミントン練習は壁打ちを1時間ほどした。複数のシャトルを使ってそれぞれの違いなどを検証してみた。シャトルによって壁打ちのやり方が変わってくることがわかっておもしろかった。壁打ちを終えてから軽く縄跳びをした。

壁打ちの研究

昨日の続き 。動画の解説やアドバイスを参考にしながらいろいろなシャトルで壁打ちしてみた。

バドミントンを始めるときに amazon でシャトルを検索すると、いろいろな種類のシャトルが販売されている。どのシャトルを買ってよいか最初のうちはよくわからなかった。いくつか買ってみて試すうちに違いがわかってきてシャトル選びのノウハウも得た。あらためて単価を算出してみるとアウトドア向けは専用設計だから割高になってしまうことも伺える。

  • エアシャトル (アウトドア向け, 単価660円)
  • メイビスフィールド2 (アウトドア向け, 単価440円)
  • エアロセンサ200 (水鳥羽, 練習用シャトル, 単価225円)
  • メイビス40 (ナイロンシャトル, 単価233円)
  • メイビスフィールド (アウトドア向け, 単価380円)

体育館でバドミントンをするならエアロセンサを買えばよい。ナイロンシャトルは耐久性があると聞くが、趣味でやる程度ならそんなに消耗しないのでエアロセンサで数ヶ月は使えると思う。アウトドア向けならメイビスフィールド2がよく反発して遠くへ飛ぶので打ち合いしやすいと思う。エアシャトルはコルクが硬くて重い分だけもっとも飛距離も速度もでると推測されるが、まだ打ち合いしたことがないので未知数でもある。

閑話休題。それぞれのシャトルで壁打ちしてみた所感をまとめておく。コルクの素材によって壁にぶつかったときの反発力が大きく違う。反発力の強いものから並べると次になる。

  1. エアシャトル
  2. メイビスフィールド2
  3. ↑ 壁との距離を変える基準 ↓
  4. メイビスフィールド
  5. エアロセンサ200, メイビス40

しかし、エアシャトルはコルクが硬いせいか、どこに跳ね返ってくるかわからない。エアシャトルはリフティングするのももっとも難しい。うまく打たないと変な方向に飛んでいってしまう。そしてエアシャトルで壁打ちするのは物理的に無理だと思う。そうすると、メイビスフィールド2がもっとも反発力が強いと言える。エアロセンサ (またはメイビス40) の反発力はもっとも弱い。同じ位置で壁打ちすると、メイビスフィールド2と比べてシャトルが返ってくるまでに時間の余裕があることに気付いた。メイビスフィールド2で壁打ちするときは壁からさらに離れて距離を取るとよいことに気付いた。メイビスフィールドはメイビスフィールド2と比べて反発力が弱い。反発力が弱いという特性は必ずしもデメリットではなく、キャッチの練習はしやすいし、ロビングで真上に上げるときも強く打っても高くあがりにくいため (天井に届きにくい) 、ラケットのスィートスポットで捉えられているかどうかのチェックもしやすい。シャトルそれぞれの特性にあわせた向いている練習というのはあるように思える。

エアロセンサを打つと カコン という乾いた音が鳴り、打っていて気持ちがよい。壁打ちするとシャトルは傷んでしまうかもしれないが、単価比較したらエアロセンサは安いから打ち心地を優先するのもよい。もしくはメイビス40もあまり反発しないから耐久性のあるナイロンシャトルで代用するのもよいかもしれない。まだそんなに使っていないから水鳥羽とナイロンシャトルの耐久性の違いを私はまだ実感できていない。1日数十分程度の練習ならエアロセンサでもよいかもしれないと考え始めた。

壁打ちしていて打ち返しやすいパターンとそうではないパターンがある。打ち返しやすいのは、自分の身体の前の得意なポイントにシャトルを呼び込めているとうまく打ち返せる。動画でもシャトルの前に移動するのが大事だと説明していた理由を理解できた。シャトルが返ってきたところにラケットを伸ばしてただ打ち返そうとしてもうまく打てない。シャトルが返ってくる軌道を見定めて、自分が打ちやすいポイントにシャトルを呼び込んでからラケットを振り抜いて打ち返す方がうまくいく。そのためにはフットワークを使ってカラダをシャトルの前へ移動させないといけない状況もある。ラケットを振り抜くと速度が速くなってしまい、メイビスフィールド2だと距離を取らないとその次のシャトルが戻ってくる速度に対応できない。

壁打ちするときにグリップの上下の握る位置を変えてみるとラケットコントロールも変わってくる。グリップの上の方をもつ (ラケットを短くもつ) と小回りがきくからコントロール重視になる。グリップの下の方をもつ (ラケットを長くもつ) と回転半径が大きくなる分パワーを加えたり、遠くのシャトルに届くといった利点がある。ある動画ではシングルスのときは長めに、ダブルスのときは短めといった持ち方をするという一般論や、昔はラケットが重かったから短めにもつのが主流だったが、いまのラケットはフルカーボン素材で軽くなったから長めにもつプレイヤーが増えたという話しも聞いた。いくつか動画をみた感じだと、グリップの持ち方や握る位置はそれぞれのプレイヤーが別々のことを言っていて自分にあったスタイルならそれでよいように思えた。基本はイースタン/ウェスタングリップになるが、個々人が打ちやすいように微妙にカスタマイズしているように思えた。動画の解説者によっては握り方はそれほど重要ではないと説明している人もいた。イースタングリップを意識しながら持ちつつ、真正面のシャトルをウェスタングリップに持ち替えて打つといった練習もしてみたが、なかなか壁打ちが続かない。何度も反復してその切り替えに慣れていく必要がある。

シャトルとスピード番号

以前 ラケットを購入した バドミントンプロショップチャンプ で練習用シャトルを1ダース購入した。paypay で買うと2,850円、現金で買うと2,700円になる。いま買ったらスピード番号が4だった。9月末にラケットと一緒に購入したときのスピード番号は3だった。バドミントンのシャトルにはスピード番号というのがあり、気温によって速度ではなく飛ぶ飛距離に差が生じるために飛びやすさを季節によって飛びやすさ調整しているらしい。スピード番号が高い方が遠くまで飛ぶ = 気温が低いときに使うシャトルになるとのこと。いまは暖かいから3番と4番があればだいたい1年は過ごせそう。

シャトルすくい

次の動画の1分20秒からシャトルをすくう練習方法を説明している。上手い人はラケットでシャトルを拾っている。これも初心者は簡単にはできない。これならオフィスや家でも練習できるかもしれない。その続きに相手がいるときの基礎打ちで同じ位置にシャトルを打ち返す練習を紹介している。壁打ちをしていて同じ位置に狙って返すことが全然できないと気付いてきた。野球のキャッチボールでも同じようなことを言われるが、特定の位置へ狙って返すというのは球技を問わず基本の所作になるんだなと思えた。

壁打ちの研究

今日のバドミントン練習は公園と近所のビルの軒下で1時間ほど行った。

みなとのもりの運動

前回の所感 。エアシャトルで打ち合いしてみたくて企画した。知人が来てくれる予定ではあったけど、急遽予定が変わってしまったようでドタキャンになって普通に運動して練習してきた。

ジョギング3周 1.4 km、縄跳び15分で1561回、今日は土の上で跳んでみた。ひざへの負担は低いものの、リズムがあわなくてコンクリートの上で跳ぶよりも多くミスした。回数も150回ほど少なくなった。跳ぶ地面がコンクリートと土で大きく異なることを実感した。個々の運動の合間にストレッチもたくさん行った。

その後にバドミントン練習をした。エアシャトルでリフティングを10分ほどやってウォームアップしてから ひとり練習の動画でみたロビング を試してみた。調子に乗っていたらエアシャトルを木の枝に引っ掛けてしまった。冬になったら葉が落ちて自然に落ちてくるかなぁ。エアバドミントンを行う風速の基準は3-4m/sが基準になる。今日の風速は4-5m程度だった。雨が降る少し前から風が出てきたときはシャトルが流れ過ぎてちょっと無理だなと感じた。ロビング (頭上にシャトルを打ち上げる) を向かい風に向かって打つことでまさに動画でみた通りにシャトルが戻ってきておもしろかった。なかなか連続ではできないが、よい角度で思いっきり打つとちょうど同じ位置にシャトルが戻ってきてもう1度打ち込みできる。

雨が降りそうな雰囲気が出てきたところで公園から撤収していつものビルの軒下へ。屋根があるから雨天練習場でもある。メイビス2で壁打ちを15分した。前にみた壁打ちの動画 でまずは10回続けられるのを目指そうと解説していたのでそれを目標に練習してみる。うまくいくときで10回程度、ほとんどは数回で失敗してしまう。壁打ちすら私にとってはかなり難しい。これはエアシャトルでリフティングを始めたときも ほとんどは20回も続かなかった 。その後1ヶ月ほど練習して、いまは大抵50-100回は続くし、うまくいくと300回を超える。壁打ちも10回も続かないところから練習して回数を増やしていく。

シャトルを壁に打ちつけても器物破損にはならないとは思うが、ビルの関係者にとって気持ちのよいものではないだろう。いつかビルの壁打ちは怒られるかもしれない。そのときのために壁打ちできる他の場所も探していこうと思う。また時間のあるときに屋根と照明があって人がこない壁を探しにいこうと思う。

壁打ちの研究

壁打ちがおもしろくなってきたのでまた別の動画をみた。

この動画のコーチもよい音を鳴らして壁打ちしている。上級者はみんなシャトルを打ったときによい音が鳴る。この音を鳴らしたいというのが私の目標でもある。動画で壁打ちのスキルアップをレベル別に解説している。こういうのはとても助かる。足はスタンスを広めにし、リアクションステップがよいとのこと。リアクションステップとは、相手が打った瞬間に着地してその反動を利用して動くという動き出しを速くするためのフットワーク。足音を小さくなっているとよいらしい。

レベル1

  • 得意な手の持ち方でずっと打つ
    • 私はバックで打つ方が得意になる (多くの人がそう?)
  • 壁の同じ位置に打てば同じところへ返ってくるのを自分のペースで打つ
    • 速く打てば速く返ってきて打ち返しが間に合わない

レベル2

  • バックとフォアを交互に打つ
  • シャトルをクロスに打ち返すと交互になる
  • ラケットの持ち替えをがんばるのが大事
    • 私はフォアとバックのラケットの持ち方を理解できていない
    • バドミントン教室へ行ったときに教えてもらおうと思う

レベル3

  • 壁に近づく
  • シャトルの方へ自分が動いていく

上級者向け

  • 壁から返ってきたコルクが自分の方を向くまで待って打つ
    • リフティングしていてもコルクが下を向いているときと曲がっていたりスピンしたりしてるとミスをする確率が高くなるのを私も実感している
  • 自分の打った速さで返ってくる、仕掛ける・流すの実践練習をする
  • 打つポイントを決めてその位置へ動く

ストレッチ

今週は木・金以外の曜日を運動した。今日も午前中はしっかりカラダを動かしたのでストレッチで状況を確認するにはちょうどよい。ころんで痛めた腰の張りはなくなっていた。右足全般の関節周りがやや痛いのと、左右ともに太ももの後ろの張りが強かったように思う。週の半ばでは右足の前太ももの張りもあったものの、その後の運動や休養で回復したのか、今日のストレッチ中にはとくに張りを感じなかった。木・金を休んだせいか、よい感じに筋肉痛の疲労も抜けていたように感じた。今日の開脚幅は開始前150cmで、ストレッチ後154cmだった。今週はストレッチもたくさん出来たので開脚幅の数字は伸びるかと期待したが、いつも通りだった。

モジュールは複数データソースに依存させない

デバッグしていて遅くなり、帰ってから慌ててスーパーに買いものへ行ったりしていて時間がなくなったので今日はバドミントン練習をお休み。

データベースとメッセージキューの整合性を考える

昨日の続き。トランザクションを導入したことで mongodb と mq でのデータフローが意図せず変わってしまっていることが調査してわかった。

従来は次のように動いていた。

  1. api サーバーがエントリー情報を受け取る
  2. api ハンドラーがエントリー情報を mongodb に保存する
  3. api ハンドラーがメッセージを管理するジョブ情報を mongodb に保存する
  4. api ハンドラー内の producer が rabbitmq にメッセージを送信する
  5. consumer がメッセージを受信する
  6. consumer が mongodb からジョブ情報を参照する
  7. api ハンドラーがレスポンスを返す
  8. consumer がメッセージを処理する

トランザクションを導入したことで mongodb にデータが保存されるタイミングが変わってしまった。

  1. api サーバーがエントリー情報を受け取る
  2. api ハンドラーがトランザクションを開始する
  3. api ハンドラーがエントリー情報を mongodb に保存する (この時点では未コミット)
  4. api ハンドラーがメッセージを管理するジョブ情報を mongodb に保存する (この時点では未コミット)
  5. api ハンドラー内の producer が rabbitmq にメッセージを送信する
  6. consumer がメッセージを受信する
  7. consumer が mongodb からジョブ情報を参照するが、トランザクションがコミットされていない可能性がある
  8. api ハンドラーがトランザクションをコミットする
  9. api ハンドラーがレスポンスを返す
  10. consumer でエラーが発生する

処理の流れを見直して次のように改修した。内部実装の都合があってやや煩雑な変更となった。

  1. api サーバーがエントリー情報を受け取る
  2. api ハンドラーがトランザクションを開始する
  3. api ハンドラーがエントリー情報を mongodb に保存する (この時点では未コミット)
  4. api ハンドラーがメッセージを管理するジョブ情報を mongodb に保存する (この時点では未コミット)
  5. api ハンドラーがトランザクションをコミットする
  6. api ハンドラー内の producer が rabbitmq にメッセージを送信する
  7. consumer がメッセージを受信する
  8. consumer が mongodb からジョブ情報を参照する
  9. api ハンドラーがレスポンスを返す
  10. consumer がメッセージを処理する

これは単純にトランザクションのコミットタイミングと mq へのメッセージ送受信のタイミングを見直せばよいという話しではない。本質的に mongodb で管理しているジョブ情報と rabbitmq へ送信しているメッセージの整合性を保証することはできないということを表している。producer はメッセージ送信に失敗する可能性があるから、そのときにジョブ情報を書き換える必要はあるが、その前にトランザクションをコミットしてしまっているため、api ハンドラー内でデータのコミットタイミングが複数になってしまう。トランザクションを導入したメリットが失われてしまい、Unit of work のパターンも実現できない。consumer の処理に必要な情報を mongodb にあるデータとメッセージの2つに分割しているところが整合性の問題を引き起こしている。アーキテクチャ上の設計ミスと言える。consumer の処理に必要な情報はすべてメッセージに含めてしまい、メッセージを処理した後に mongodb に結果を書き込むといった設計にすべきだった。

初期実装のときからジョブ情報を mongodb で管理する必要はあるのか?という懸念を私はもっていた。要件や機能が曖昧な状況でもあり、メンバーもなんとなく db に管理情報を残しておいた方が将来的な変更に対応できて安心といった理由だったと思う。当時は整合性の問題が起きることに、私が気付いていなかったためにこの設計を見直すように強く指摘できなかった。トランザクションを導入したことで consumer が必要な情報を db に保持すると、db とメッセージ処理のタイミングにおける整合性の問題が生じるという学びになった。

いまとなってはこのジョブ情報を使う他の機能もあるため、この設計を見直すことはできない。今後の開発プロジェクトで db とメッセージを扱うときはこの経験を活かすためにふりかえりとして書いておく。

久しぶりにコードリーティングイベントに参加

久しぶりにコードリーティングイベントに参加

今日のバドミントン練習はメイビス2で壁当てを15分した。勉強会帰りで疲れていたせいか、夜遅くのせいか、あまりカラダが動かなかった。日付が変わってから 中学校体育館の12月予約 で4つ抽選申し込みをしていたが、すべて落選していた。2ヶ月続けてすべて落選したことからそうそう予約は取れないことがわかってきた。

昼間は昨日の続きで mongodb のトランザクション導入のマージリクエストをレビューしてもらって、テスト環境へデプロイして検証していた。id 連携のシステム間連携において意図した振る舞いにならなくてその調査をしていた。チーム勉強会で mongodb のトランザクション周りのいろいろをメンバーに共有した。17時前にお仕事を終えて定期歯科検診へ行ってきた。前回対応してくれたスタッフさんで「また少し痩せました?」と聞かれた。8月からだとほとんど変わっていないと思うが、今週は普段より多く運動できているのでその影響もあるのかもしれない。30分ほどですんなり終わった。

コードリーティング

歯医者を終えてから KOBE.go #7 - コードリーディング会 へ行ってきた。移転したハックバーへ行くのも初めて。三ノ宮駅から10分ほど歩いた場所の、こじんまりしたバーだった。10人程度入ったらいっぱいかな。おそらく集客や家賃などを考えたら妥当なサイズと立地なのだと推測する。いまは水-日の18-23時、月・火がお休みという営業時間らしい。私が着いたときはカウンターが埋まっていたのでテーブル席で発表を聞きながらコメントしたりしていた。私以外の参加者の大半は学生さん、みんな20代の方ばかりだったと思う。kyoto.go で発表したりしていたせいか、kobe.go のスタッフさんにも名前を覚えてもらえていた。若い人がコミュニティを運営しているのはよいことだと私は考えている。年寄りの役割としてなにかしらコンテンツを提供することで協力できればと思う。

コードリーティングはおくたにさんという方が実装している gomoqt という Media over QUIC (MOQ) のサーバー/クライアントを題材とした。京都大学の学生さんで学生起業しているのかな?音声配信サービスをやりたいから moq ライブラリを開発していると話されていて、プロトコルを勉強して自前でサーバー/クライアントのライブラリを実装しようとするの、すごいなと思って聞いていた。quic のライブラリを使ってサーバー/クライアントを実装しているようにみえた。ソケット (トランスポート層) より上のレイヤーを実装すればよいならそんなに難しくはない。

私が想定するコードリーティングのイベントではなかったものの、参加者は誰も moq プロトコルを知らないので moq の背景や現状、プロトコル仕様を共有するようなイベントになっていた。それはそれで私は知らないことばかりなのでへーと思いながら聞いていた。21時半頃にはイベントも終わり、イベント告知や雑談モードになっていって、若い人たちの中におっさんがいても迷惑かなと22時前には退出した。帰る前にワンドリンク (Go という名前の柑橘系カクテル) の料金として700円を支払う。個人的にお酒を飲みながらの勉強会はあまり好きではない。気分や雰囲気でぐだぐだになる印象があって学ぶときは学び、終わってから飲みに行って雑談するといった切り替えが私は好み。バーで勉強会をするという雰囲気もあまり馴染めない。単純に狭いし暗いし椅子よくないし作業に集中しにくいという所感かな。

シャトルの壁打ちの研究

今日のバドミントン練習はエアシャトルでリフティングを10分した。連続最大回数は275回。リフティングをしてからシャトルを真上に強く打つのを10分、シャトルを反発力の高いメイビス2にして壁打ちを15分していた。シャトルを強く打つときにチカラの入れ方や角度などを考えながら打ってみた。壁打ちも練習していて2パターン思いついた。1つは壁の近くでひたすらシャトルを打ち返すやり方、もう1つは少し壁から距離をとって真上にシャトルをあげて落ちてきたシャトルを思いっきり振り抜いて壁に向かって打つ。壁から返ってきたシャトルをまた真上にあげて、思いっきり振り抜くのを繰り返す。このやり方だと素振りの延長上でラケットを振る練習になるような気がする。

昨日まではジョギングしてからバドミントンの練習をしてきた。今日は逆にバドミントンの練習をしてからジョギングと縄跳びをした。お仕事を終えたのが20時頃で21時にバドミントン練習場 (ビルの軒下) の照明がおちる。だから先に照明が消える前に先にバドミントンの練習をすることにした。おかげで壁打ちのやり方をひらめいたりして約1時間集中して練習していた。その後、みなとのもり公園へ移動してジョギング2周 (0.9km) と縄跳び15分で1770回跳べた。昨日からの筋肉痛も続いているので軽めに運動しようと思ったものの、縄跳びは少し回数が増えた。休憩時間を少し減らしたり、ミスが減ったり、バドミントン後のせいか腕がだるくて縄をまわすリズムにのれなくてペース落ちたりと、昨日とはコンディションがいろいろ違うなと思いながら数字をみるとおもしろい。

お仕事は昨日の続きで mongodb のトランザクションのデバッグをずっとやってた。デバッグしての結論として middleware で unit of work を実装するのは断念した。

メガネ探し

視力が 0.3 ぐらいで有事のときに困る状況を想定してメガネを1つもっておこうと考えている。やぎさんにも相談していくつかアドバイスをいただいた。動体視力も落ちていてバドミントンをしていて動くシャトルを空振りすることも多い。もしかしたらメガネをした方がシャトルとの距離感もつかめるのかも?と思いスポーツ用のメガネがどうなのかも調べてみた。結論から言うと、スポーツ用途ならメガネよりもコンタクトレンズの方がよいらしい。コンタクトレンズをするほど視力低下に困っているわけでもないからまずはメガネを買って必要なときだけ使うといった運用を考えている。

壁打ち

次のバドミントンの練習方法として壁打ちがよいんじゃないかと調べてみた。上級者の動画をみると、近くで力強く打ち返して壁打ちしている。これはめちゃくちゃ難しい。シャトルが速過ぎて全然おいつかない。実際にやっている人をみるとこのぐらいはできるんやとわかってやり方のイメージづくりにはよい。

もう1つ。室内でスポンジボールを打ち返す壁打ちを取り上げているサイトもあった。これならオフィスでもできるんじゃないかとベルボールを amazon で発注してみた。出張にももっていってホテルでやってもよいかもしれない。

mongodb のトランザクション調査

今日のバドミントン練習はエアシャトルでリフティングを10分、連続最大回数は120回ほど、ショートサーブ30回した。フットワーク練習はお休み。筋肉痛もあったから、みなとのもり公園をジョギングで3周 1.4km、縄跳び15分で1712回だった。縄跳びも2ヶ月ぶり。8月に過去最高が1838回に対して、2ヶ月ぶりにやって2分弱の休憩、十数回のミスがあっても1700回を超えるんやと思って少し驚いた。8月に比べたらいまは涼しいから記録が伸びるのもある。ジョギングで足が筋肉痛になると走るよりも縄跳びの方が負担が小さい。昨日と同じように運動してストレッチして十分にカラダを動かした。

トランザクションとコールバック

お仕事は昨日の続きでリクエスト途中のサービス終了したときに web api ハンドラーの処理が途中でキャンセルされ、そのために内部のデータが不整合になることがわかった。データを不整合にしないため mongodb のトランザクション の仕組みを調べてデバッグしたりしていた。echo のミドルウェアで Unit of work を実装できないかをプロトタイプ実装していた。

基本は次のように callback 関数を渡せばトランザクションに失敗したときにリトライもしてくれて便利なのだけど、いろいろ api サーバーの既存アーキテクチャの都合もあってこれは使えないことがわかった。

session, err := client.StartSession()
if err != nil {
	return err
}
defer session.EndSession(ctx)
result, err := session.WithTransaction(ctx, callback)

部屋の片付けへの趣き

今日のバドミントン練習はエアシャトルでリフティングを10分、連続最大回数は322回だった。その後にショートサーブ30回、フットワーク10分の練習をした。リフティングは連続回数よりもラケットコントロールの質を求める練習に変えていく。昨日と同様、みなとのもり公園をジョギングで4週走った。fitbit によると 1.8km 走ったそうな。

プロジェクトマネージャーが手を動かすことの功罪

朝からお手伝い先の社内インフラサーバーが落ちていて待ち時間があったのでふと思い返してつらつら考えごとをしていた。

お客さんが選ばなければ、逡巡と葛藤の結果、最終的に私は品質を優先する

開発合宿の課題管理の雑談から引用

私はもっと仕組みを作るところに注力すべきだった。私自身がコンサル嫌いの、実務をやっている姿勢をみせてメンバーが参考にしてほしいという意識が強過ぎた。また開発は楽しいことから必要以上に手を動かし過ぎてコアな開発に入り過ぎたことで、自分がやらないと他のメンバーが担当しにくい体制になってしまった。「任せる」はずが「任される」ことになってしまった。バックエンドの品質は大事だから責任感もあった。もしかしたらお客さんが求める以上の過剰品質なモノづくりをしてしまったのかもしれない。そして、仕組みづくりの後はメンバーへ委譲すべきだった。いまメンバーへマネージャーを委譲しているが、マネージャーという業務はもともと得意でもなくこだわりもなかったがためにすんなりと委譲できた。

しかし、開発の方は得意分野、且つ好きであるために品質にこだわってしまう傾向があることを認識できた。そのことが裏目に出てしまった。これが自社プロダクトの開発ならばすべて自社の資産になるためにそれでもよかったかもしれないが、他社プロダクトでやってしまうと、自分の時間を必要以上に注ぎ込むことになってしまった。その結果、お客さんの信頼を得られてはいるものの、自社プロダクトの開発に着手できず、クロージングの時期が遅れて微妙な状況になってしまった。もしかしたら、お客さんもうちの会社との契約を終了できなくなってしまって困っているという考え方もできる。

rabbitmq の autoAck (noAck) の振る舞い

先週の続き 。id 連携のリクエストをし続けながら compose サービスを down させたときの振る舞いを検証する。理想的にはそれぞれのモジュールのサービスが graceful に振る舞って、それぞれの永続化する場所でデータが溜まってくれることを期待している。その1つがメッセージキューでもある。Persistence Configuration によると、rabbitmq のメッセージを永続化するには queue に対して durable の設定を行い、producer が送信するメッセージに対しても persistent の属性を付与すればよい。しかし、実際に検証してみると、サービスの再起動時にメッセージキューからメッセージが消失していることがわかった。consume メソッドに渡す仮引数に autoAck というパラメーターがある。コメントにもそれっぽいことが書いてある。

When autoAck (also known as noAck) is true, the server will acknowledge deliveries to this consumer prior to writing the delivery to the network. When autoAck is true, the consumer should not call Delivery.Ack. Automatically acknowledging deliveries means that some deliveries may get lost if the consumer is unable to process them after the server delivers them. See http://www.rabbitmq.com/confirms.html for more details.

ConsumeWithContext

autoAck という名前からメッセージを取得したら自動的にそのメッセージに対して ack を返すようなイメージで私は考えていた。しかし、どうやら consumer が subscribe して接続した時点で consume 扱いとなり、consumer がメッセージを実際に取得したかどうかに関係なく consumer の終了時にそのときに溜まっているすべてのメッセージが消失しているようにみえる。余談だが、rabbitmq のドキュメントにも noAck と autoAck という2つの用語が存在する。どうやらもともと noAck という名前だったのを autoAck という用語に変更したようにみえる。メッセージを永続化するには autoAck=false にしてメッセージに対する処理を完了した後に consumer が必ず ack を返すという実装にしないといけないことがわかった。このパラメーターは2年前から同じ設定だったので私がいま検証するまで誰もこの振る舞いに気付かなかったんやと驚いた。

部屋の掃除

19時に閉まる業務スーパーへ買いものへ行くために18時過ぎにお仕事を終えて、移動して買いものをして、炊飯開始して、ジョギングして、戻って晩ごはんを食べて、バドミントン練習をして、お風呂に入って、ストレッチして、なんとなくベッドに入って休もうとした。ここで22時半ぐらい。まったく眠れなくて寝室の掃除を始めたら、これが捗ってやる気が出てきて、部屋のレイアウト変更したりして少し片付けもできた。引っ越してからまったく進めていなかった部屋づくりが突発的に急に少しできた。これまでも時間がなかったわけではないが、まったくやる気がなくて手をつけられていなかった。それがなぜできたのかはわからないが、手をつけられていなかったことに手を入れられたことで心理的に楽になった気がした。明日も帰ったら少しだけ部屋づくりの作業をしようと思う。

ほぼお休み

今日のバドミントン練習はリフティングを5分、フットワークを10分した。久しぶりにリフティングしたら距離感が鈍っているかと思いきや、100回は簡単に超えられた。リフティングをするのも少し飽きてきたので他の練習もやっていこうと思う。練習前に無性にカラダ動かしたくなったので 1.8km ほどジョギングで走ってみた。

期日前投票

兵庫県知事選挙 の期日前投票へ行ってきた。元知事のさいとうさんも追い上げしているみたい。来週末が投票日になるので結果がどうなるのか楽しみでもある。

2人の自殺者のうち、1人は告発された方でもう1人は次の優勝パレードの寄付金を募る企画の責任者だったと思う。表向き補助金のキックバックとは認められてはいないが、不可解なお金の流れがあるのでかなり黒に近い灰色にみえる。百条委員会が進むうちにこの疑惑の検証も進むのではないか?と当初は考えていたが、そうでもなくなっていないみたい。もしくはこれは副知事がやったことで知事の過失とはみられていないのかもしれない。

タスクをこなす日々

以前みた動画で 日々の変化を感じる のが大事だとあった。少し意識して普段やらないことをしてみたり、買いものするモノを変えたりしてみていた。またマンネリになってきたのでそのことを思い出していた。梅原さんの言う 義務感によって受け身の状態になってしまう 状態そのものである。

以前はやりたいことがいくつかあったし、そのための調べものも少しずつ進められていた。夏場は開発者としてお仕事のよくない部分を直すというところに集中したものの (その成果も十分に出た) 、一時期のその繁忙期をすでに過ぎていていまはそれほど忙しくないにも関わらず、心が空き時間を何に使うかということについてこない。いまのプロジェクトの課題に気付き過ぎてすべてに対応できない状況にストレスを感じているところも多少はある。そうであっても、新しいことを学んでいて楽しいとか、日々の生活に活気があるとか、そういう状態ではなくなってしまっている。5月頃は運動をして体脂肪を減らす日々が本当に楽しかった。それが当たり前になってしまったというべきなのか。2024年1月まで運動はほとんどやっていなかったのだから、運動をやるようになって単純に他のことをしていた時間を取られているという考え方もある。一方で運動によって健康にはなっているし、バドミントンという趣味や新たなコミュニティの土台づくりにもなっているから、これはこれでよい方向に変化したとも考えられる。

テストカバレッジの LT 発表

今日のバドミントン練習はお休み。

LT 会

午後から LT大会 with カメラマン に参加してきた。副業でカメラマンをやろうとしている方が LT 中にプロフィール写真になるようなものを撮ってくれるという。会社紹介などのスライドで使えるかもしれないと思って参加してきた。趣味で4-5年カメラを勉強しているというだけあって、機材や知識も備えていてよかったと思う。LT のネタとして先月お仕事でやっていた go のテスト改善の一環でカバレッジについての紹介をしてきた。サンプルコードは次になる。

終わってから軽く立ち飲み屋で飲んで若い人たちの話しを聞いていた。若い人たちは活気があってやりたいことも多くて、いまの私からみたときのモチベーションの在り方に違いがあるようにも思えた。たまに若い人たちの中に紛れて話しを聞くだけでも自分が失くしたものを気付くきっかけになるようにも思えた。若い人たちはどんどん挑戦してがんばってほしい。

ストレッチ

今日は身体的に疲れているというよりも、開発合宿から続くお仕事のせいか、精神的に疲れていて、2週間ぶりにトレーナーさんと雑談するだけでも気分転換になってよかったと思う。今週はお仕事に集中していてまったく運動していないため、足の張りなどはほとんどなくなっていた。一方でバドミントンの試合をしてこけたときに痛めた腰だけはまだ張りが残っていてなかなか治りきらないことも実感した。今日の開脚幅は開始前149cmで、ストレッチ後155cmだった。

ストレッチを終えてから買いものしてオフィスへ戻って軽く作業していた。

開発者合宿のふりかえり

今日のバドミントン練習はお休み。

隔週の雑談

顧問のはらさんと隔週の打ち合わせ。今日は先週末の開発合宿のふりかえりをした。

  • 1週間前ぐらいに参加者を集めて事前打ち合わせをして過ごし方の共有をした方がよかった
  • 周りと雑談してしまうので資料を合宿中に作るのはほとんど時間を取れない
  • もう3回目なのでお風呂へ入るのにも慣れが出てきてお気に入りの外湯へ行くようになった
  • 人数はどのぐらいが適正か?
    • 5人という人数は中途半端だったように思える
    • 8人は多過ぎた気はするから6人がちょうどよいのではないかと思える
  • 周辺の体験イベントにみんなで参加してみるのもよいかもしれない
    • あらかじめ希望をとっておく
  • 発表の時間を初日と2日目に分割したのはよかった
    • 夜に発表を固めなくてもよい
    • お昼でも夕方でもみんなが集まっている時間帯にさらに分散させるのがよさそう

細かいところはいろいろあるけれど、覚えているうちに意見をもらった。いつもはらさんが来てくれるから私の負担が低くなり本当に助かっている。

compose サービスの停止の振る舞い

昨日の続き 。それぞれのサービスに depends_on を指定することで依存関係を定義できる。サービス起動時と停止時に依存するサービスが先に起動または停止するように順番を制御してくれる。但し、起動時のデフォルトはコンテナ起動をトリガーにするため healthcheck などを指定しないと厳密にサービスが起動しているかどうかはわからない。

compose サービスの起動は次の2つのコマンドがある。

  • up: すべての依存関係を調べてコンテナサービスを起動する、停止しているコンテナがなければ作成する
  • start: 停止しているコンテナのみを起動する

基本的には up を使っておけば運用上の問題は起きない。start を使う理由がなければ up を使うといった感覚でよい。一時的なメンテナンスなどで stop を使ってコンテナを停止し、そのコンテナだけ起動すればよいことがわかっていれば start を使った方がオーバーヘッドが少ないといったメリットはあるだろう。up と start の違いはそれほど気にしなくてもよい。

次に compose サービスの停止は次の2つのコマンドがある。

  • down: コンテナを削除する、関連するリソース (volume や network) もすべて削除する
  • stop: コンテナを削除せずに停止する

運用上どちらか一報を覚えておくなら down を使えばクリーンに再起動できると言える。コンテナが使うイメージのバージョンアップをするときなどはコンテナを削除する必要があるから down する方が手間がいらない。stop で停止したコンテナがあると、up でも start でもバージョンを自動的にあげてくれたりはせず、ただ停止したコンテナを起動するといった振る舞いになる。そのため、バージョンアップをするときは stop で停止した後に rm でコンテナを削除する必要がある。それなら最初から down で削除してしまってもよいと言える。compose の logs コマンドを使うと複数サービスのログを1つのストリームで監視できる。この状態で stop や down を実行してどういった振る舞いになるのかを検証できた。

$ docker compose logs -n 3 -f

ミドルウェアのコンテナの振る舞い検証

今日もバドミントン練習はお休み。

mongodb の healthcheck

bitnami/mongodb というサードパーティのコンテナ を使って mongodb サービスを設定している。docker compose でコンテナサービスの依存関係を記述できるが、特別な設定をしないとコンテナサービスの起動をトリガーに依存関係を制御する。実際はコンテナが起動して内部のサーバー/デーモンが正常に起動するまで少し時間がかかる。たとえば mongodb のコンテナであれば mongod デーモンに初期設定をして再起動したりといった処理を内部的に行っている。そんなときに healthcheck を使うことで実際に mongod デーモンに接続できるかどうかでコンテナのサービス間の依存関係を制御できる。

これまで mongodb には healthcheck の設定をしていなかったので調査して次の設定を追加した。

healthcheck:
  test: mongosh "mongodb://localhost:37017/test?directConnection=false&replicaSet=${MONGO_REPLICA_SET}" --eval 'db.runCommand("ping").ok' --quiet
  interval: 60s
  timeout: 5s
  retries: 3
  start_period: 30s
  start_interval: 3s

mongosh で db に接続して ping を実行するだけなら認証は必要ない。mongosh でなにもパラメーターを指定せずに接続すると direct 接続になってしまう。replica set の設定が完了していることを検証するために replica set 接続にしている。また interval は起動中もずっと死活監視に test コマンドを実行している。それとは別に start_interval を指定することでサービス開始時と通常の運用時の test コマンドによる制御をわけて管理できる。

rabbitmq のアップグレード

19時過ぎに業務終了報告をして、帰ろうと思ったときにふと rabbitmq のバージョンを最近あまり確認していないことに気付いた。いま 3.12.14 を使っているが、Release Information をみるとコミュニティサポートは切れていて、現行バージョンは 4.0 になっていることに気付いた。試しに結合テストの rabbitmq のバージョンを 4.0.3 に上げてみたところ、問題なく動作している。テスト環境の移行は他のメンバーが使っていない夜にやった方がいいかと帰ることをやめて普通に移行作業をやり始めてしまった。メッセージキューは永続化したデータを基本的には保持しないため、メジャーバージョンアップで互換性がなかったとしても volume 配下のデータを削除して exchange/queue を移行すればよい。

rabbitmq の http api client として rabbit-hole というツールを使っている。それも v2 から v3 へアップグレードしていて Changes Between 2.16.0 and 3.1.0 (Oct 31, 2024) に書いてあるが、機能的な変更も非互換の変更もいまのところはないが、4.0 にあわせて将来的に非互換な変更をやりやすいよう、メジャーバージョンを上げると書いてある。go.mod の依存関係も更新したりした。

19時過ぎに帰ろうと思ってから、なんやらかんやらしているうちに最終的には21時半まで作業していた。