Posts for: #2024/11

compose 環境のバックアップ

今日は溜まった日記をまとめて書くためにバドミントン練習はおやすみ。

コンテナの環境変数の再利用

朝から rpm パッケージングのリファクタリングをしてインストール検証をした後、バックアップスクリプトの調査をしていた。コンテナの環境変数は次のようにして取得できる。

  • 環境変数をすべて表示
$ docker compose exec mongo env
  • 任意の環境変数の値を取得
$ docker compose mongo printenv MONGODB_PORT_NUMBER
  • パスワードの隠蔽

コンテナ内の mongodump を実行するときにパスワードを隠蔽するにはパイプを使って標準入力から渡す。

$ echo ${passwd} | docker compose exec --no-TTY mongo mongodump --authenticationDatabase admin --uri mongodb://${user}@localhost:27017 --db mydb --archive > mydb.dump

tar ball によるバックアップ

普通に tar ball を作ると次のようになる。

$ tar --exclude path/to/dir/subdir1 --exclude path/to/dir/subdir2 -czf backup.tar.gz path/to/dir

お手伝い先の社員さんに zstd という新しい圧縮アルゴリズムを使う方がよいとアドバイスをもらって変更した。別途 zstd のパッケージはインストールしておく必要がある。

$ tar --exclude path/to/dir/subdir1 --exclude path/to/dir/subdir2 --zstd -cf backup.tar.zst path/to/dir

バドミントンしただけの休日

今日のバドミントン練習は体育館で1.5時間ほど練習した。久しぶりに相手がいて打ち合いできて楽しかった。

体育館でバドミントン

前回の所感 。朝から磯上体育館の個人利用のための行列に並ぶ。今日は7時52分に磯上体育館へ着いたら5番目だった。徐々に並ぶ時間が早くなっていっている気がする。本当は9時から予約するつもりだったが、他の参加者から15時がよいとのことで15-17時で予約した。実際に行ってみたら6面あるうちの2面が空いていた。個人利用の遅い時間帯なら並ばなくても予約を取れるのかもしれない。但し、確実に狙った時間を予約するためにはこれからも8時前後に行って並ぶことにはなると思う。逆に9時から予約しようと思ったら8時よりも早く並ばないといけない。

15時から2-3回休憩を挟みつつ、打ち合いして、シングルスの試合やって、移動した場所に狙って打つ練習などをした。たくさん打ち込みできたので グリップの握り を試したりもしていた。今日の収穫はバック持ちの低い軌道でシャトルを打ち返すときによい手応えを掴んだ。低い位置にあるシャトルをネットを超える高さで強く速く返せるラケットコントロールを何回かできたと思う。5回中2-3回といった頻度だからまだまだ完全に捉えられてはいない。壁打ちでもよいタイミングを掴めるときはあったのでその成果が出たと言えるのかもしれない。やはり相手がいる打ち合いは練習の幅が広がる。1人でリフティングや壁打ちするのも、もちろん重要ではあるし練習にはなるが、相手がいて打ち返してくれる方がもっとさまざまなパターンや状況に対するラケットコントロールやシャトルとの距離感を試すことができる。単純にシャトルを打っていても楽しい。

家に帰るまではバドミントン終えてからオフィスで作業しようと思っていたのに、休んだらやる気がなくなって、そのままだらだらしていた。体調悪い。

復調へ向けて休養

今日のバドミントン練習は、みなとのもり公園でジョギング3周 (1.5km) 、縄跳び1234回 (09:08)、メイビス2で壁打ちを10分した。体調崩してたくさん寝ていたのもあって体力が落ちているのもあって普段よりも軽い運動にした。

可用性検証の結果確認

お昼から昨日の可用性検証の結果を確認した。4千エントリーのユーザー/グループ追加/パスワード更新、ユーザー/グループ削除をやると mq によるメッセージにすると2万メッセージの処理が id 連携としては逐次処理となる。id 連携の個々の処理はわりと遅いのですべての処理が完了するまで約半日ほどかかった次第。そのために mq を設けている。その後、気分転換にコードを書こうと軽く mq の queue のエクスポート/インポートのサブコマンドを作った。お昼に2時間ほどお仕事をしてからストレッチへ向かった。

公職選挙法と選挙運動

先週終わった 兵庫県知事選挙 が新たな展開を迎えている。昨日の夜から公職選挙法違反の疑惑が浮上してきた。さいとうさん陣営で広報に関与した PR 会社の社長が、会社の宣伝 (自身の承認欲求?) のためにさいとうさんから選挙における広報全般を「任された」と記事に書いた。これが大炎上となっている。書いた本人に悪意はなく、公職選挙法についてよく知らずに書いてしまったという凡ミスにはみえる。

私も知らなかったから一般人は知らないと思われるが、政治に関する行為には次の2つに大別される。

  • 政治活動
  • 選挙運動

政治活動に対して報酬の支払いをすることは構わないが、選挙運動に対する報酬は公職選挙法で厳密に規定されている。その背景は選挙運動の広報に報酬を支払ってよいならお金持ちは広告をたくさん出して有利になるのは明白なのでそういったことができないように法律で禁止されているとのこと。具体的に払ってよい報酬は次のようなものになる。これ以外の労務は後援会のスタッフがボランティアとして手伝うものらしい。

  • ポスター代/選挙カー代/選挙ビラ代 (税金から支出)
  • ウグイス運動員への報酬
  • 選挙カードライバーへの報酬
  • 労務者への報酬
  • 選挙事務所費用、事務所運用経費、その他経費など

ここで選挙運動というのは、特定の選挙の、特定の候補のための行為を指していて、PR 会社の社長は広報戦略の企画立案や SNS 運用全般を「任された」と書いていることから多くの人がそれはプロの会社が報酬をもらってやっていることだよね?と勘繰っている。もし報酬をもらっていなくてもプロの会社が専門業務をボランティアで手伝うという行為は役務の提供として寄付扱いとなってしまう。政党に対する寄付は構わないが、政治家個人への寄付は禁止されていることから、報酬をもらっていようがボランティアで手伝っていようが、広報全般を「任された」という言葉を鵜呑みにすると、どちらであっても公職選挙法違反では?とかなり旗色が悪いという話しになっている。もしこの疑惑が公職選挙法違反となった場合、さいとうさんの当選は取り消しとなり、県知事選挙がやり直しとなる。もちろん選挙違反なら、さいとうさんは公民権が停止するために立候補できない。

今回の県知事選挙はさいとうさんの告発文書への対応の経緯であったり、立花さんの不当な介入だったり、異常尽くしになっているのでもうひと悶着あっても驚かないのかもしれない。いずれにしても、さいとうさんの百条委員会もまだ継続しているのでこのネタもその議題の1つになるのかもしれない。

ストレッチ

今週は出張の週でほとんど運動できていないので筋肉痛などはない。一方で出張の行き帰りで座っている時間が長かった分の、右腰の張りが強いとトレーナーさんが教えてくれた。あまり自覚症状がなかったが、車に長時間乗ったときや新幹線の移動があるときは大抵そうなる。予定外のタスクが増えていって進捗もよくなくていろいろ疲れていて、トレーナーさんと県知事選挙後の雑談をしたり時事ネタを話したりして気分転換になった。今日の開脚幅は開始前149cmで、ストレッチ後153cmだった。調子がよくない。

体調がよくなかったからストレッチを終えて真っ直ぐ家に帰って20時頃から横になって休んでいた。

web api サーバーの可用性検証

今日も体調が悪かったのと22時過ぎまでインフラ検証をしていて疲れていたのでバドミントン練習はおやすみ。

昨日の続き。compose サービスのコンテナネットワーク内で管理している nginx のリバースプロキシの設定を、ホスト os で起動する httpd (apache) に移行して検証していた。基本的にはほとんど同じ設定ができる。nginx よりも httpd の方が細かく設定したり、エラーチェックが厳密だったりの違いがあったぐらい。httpd の設定をするのも久しぶりで chatgpt に聞きながらわからないところを穴埋めしていくようなやり方で検証した。

その検証を完了してから、web api サーバーの可用性検証に取り掛かる。シェルスクリプトで数十から数百リクエストを並行にリクエストして、そのときのサーバーの状態を監視したりしながら、id 連携の処理が正常に動くことを確認する。mongodb のトランザクション導入 により、同じ主キーのドキュメントを並行に更新しようとすると WriteConflict エラーが発生する。これは仕方がない。同じコレクションであってもキーが異なればトランザクションのエラーは発生しないことを確認できた。メモリリークもみられない。web api サーバーの大半は私が設計して開発しているのでこんなレベルで問題にならないはずだが、やはり検証して確認できると安心できる。

ipv6 による疎通検証

今日は神戸へ帰ってきてバテバテでしんどかったのでバドミントン練習はおやすみ。出張で体調を崩してしんどい。

ipv6 とリバースプロキシと xff ヘッダーの扱い

要件の1つに ipv6 での通信ができることという項目がある。OSI参照モデル の概念から言うと ipv6 は第3層であるネットワーク層の話しになる。実際に世の中で運用されている tcp/ip のプロトコルスタックにおいてもネットワーク層の話しであり、レイヤーが異なることからアプリケーション層では影響を受けないはずではある。アプリケーション層からみたら ipv4 であろうと ipv6 であろうと、ネットワーク周りのライブラリやフレームワークが対応していれば問題ないだろうと考えていた。それ自体の認識は誤っていない。

プロキシを経由するときに X-Forwarded-For (以下 xff) ヘッダーをセットすると、そのプロキシへアクセスしてきたリクエスト元の ip アドレスを保持できる。api サーバーでは xff ヘッダーを参照すれば ipv4 または ipv6 でアクセスしてきたクライアントの ip アドレスがわかる。フレームワークの echo における対応 も過去に行っていた。1つ対応漏れがあって xff ヘッダーはプロキシを経由するごとに途中の ip アドレスを追加していく。原則として信頼できるネットワークのアクセス元の ip アドレスを使う。例えば、次のような xff ヘッダーを考える。

X-Forwarded-For: 203.0.113.3, 192.0.2.5, 198.51.100.7"

このとき信頼できるネットワークが 198.51.100.0/24 である場合は xff ヘッダーによるクライアントの ip アドレスは 192.0.2.5 となる。信頼できるネットワークが 192.0.2.0/24 と 198.51.100.0/24 の2つである場合は 203.0.113.3 の ip アドレスを使う。基本的には信頼できるネットワークの左側にある ip アドレスを使うと考えればよい。一方で途中経路のネットワークを知っていて信頼できるネットワークであることを設定しないと、意図したクライアントの ip アドレスを取得することはできない。

さらにリバースプロキシでアクセス制限をしたいという要件がある。docker compose を使うと通常は NAT の構成となり、コンテナネットワークのリバースプロキシ (nginx) からホスト os のリクエスト元の ip アドレスを参照できない。コンテナネットワークのゲートウェイ (172.18.0.1) からアクセスを受けたようにみえる。この振る舞い自体も正しくはあるが、調査したところ、docker の rootless モードだとリクエスト元の ip アドレスを参照できないということがわかった。次の issue によると port forwarder と呼ばれるモジュールがあり、デフォルトものから slirp4netns に変更すれば参照できると次の issue で紹介されていた。

Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=slirp4netns"

実際にやってみて ipv4 の ip アドレスを参照することはできたものの ipv6 は未対応らしい。

他のやり方も調査してコンテナネットワーク内の nginx から ipv6 の ip アドレスを参照することができなかった。要件を満たせないことからリバースプロキシをコンテナネットワークから外出しして構築することに決めた。rootless モードでなければ ipv4/ipv6 の両方を取得できるという話しもお手伝い先の同僚から聞いた。こんなところではまるとは思わなかった。

ping や curl コマンドも ipv6 対応されていてオプションを付けなくてもよいけど、ipv6 であることを明示する上では -6 とオプションを付けてもよいかもしれない。それにしても検証するときに ipv6 アドレスを手打ちするのは煩雑なのでいちいちアドレスをコピペすることになって面倒だなと感じた。

$ ping -6 2001:DB8:0:0:8:800:200C:417A
$ curl -s -6 'http://[2001:DB8:0:0:8:800:200C:417A]:8080/api'

カバレッジによるテスト改善のみえる化

昨日は睡眠不足の中、同期飲みで酔っ払ってかなりひどい状態で寝ていた。朝起きて時計の見方を誤って10時過ぎだと勘違いしたぐらいには取り乱していた。今日のバドミントン練習は雨降りでおやすみ。縄跳びをもってきたのに雨降りでできなかった。

プロジェクトの進捗報告

出張したときの月例報告の22回目。前回の進捗報告はこちら

今回の報告内容のメインはテスト改善の成果について共有した。カバレッジを取得できるようになったことでその成果を数値で共有した。マネジメントとしては数値で説明できると説得力があってよい。前フェーズからの要件や仕様変更により、テストが出来ていなかったところのカバレッジの改善が次のようになったと報告できた。わかりやすいし成果も確認しやすい。この数値を算出できるようになったことそのものも今回のテスト改善の成果でもある。

-/api/handler/ldap_management.go  46.8%
+/api/handler/ldap_management.go  77.1%

-/api/handler/ldap_profile.go  50.6%
+/api/handler/ldap_profile.go  79.8%

-/api/handler/ldap_util.go  61.4%
+/api/handler/ldap_util.go  80.4%

あとはバックエンドの開発を私がほとんどやるようになってしまって、その状況そのものがいずれ私がいなくなることや引き継ぎを考慮するとよくない状況になってしまったという懸念も共有した。すぐにいなくなるわけではないが、私がコアな開発をやっていてよいのかどうかの懸念を私自身が抱くようになってきた。これからメンバーへ徐々に引き継ぎしていくためにもテストコードが十分にあって、テストそのものが書きやすくなって、カバレッジでテスト漏れを確認できるようになっていて今後にもつながっていくだろうと報告できた。私自身がプロジェクトで窮屈に感じていた肩の重荷を少し下ろすことができて安心できるようになったと報告した。

朝の飛行機ルートの実証検証

今日のバドミントン練習は出張と飲み会でおやすみ。

朝の飛行機ルートのふりかえり

先月は出張帰りに飛行機を使った 。今回は出張の行きを飛行機にしてみた。

タイムスケジュールは次のようになった。荷造りは出来ていたので5:45に起床してすぐ出掛けた。貿易センター駅は家から近いので朝ゆっくりできる。

6:02 (ポートライナー) 貿易センター (車内わりと満員) 発
6:17 (ポートライナー) 神戸空港 着
6:28 保安場通過して搭乗口前へ (スーツケース持込可)
6:50 搭乗手続き開始
7:02 飛行機の座席に着く
7:16 神戸空港の滑走路を発進
7:21 離陸
(前日ほとんど寝てなかったので寝てた)
8:16 羽田空港の滑走路に着陸
8:25 降機 (定刻より5分早い)
8:42 (京急本線) 羽田空港 (普通に座れる) 発
9:10 (都営浅草線) 泉岳寺乗り換え (5分待ち、普通に座れる) 着
9:18 (都営浅草線) 五反田 着

新幹線だと次のスケジュールになる。普段は三宮駅へ歩いていく時間があるので5時半前には家を出ている。地下鉄にももう1本前の便に乗ったりしている。

5:53 (神戸市営) 三宮 発
5:55 (神戸市営) 新神戸 着
6:10 (新幹線) 新神戸 発
8:44 (新幹線) 品川 着
8:52 (JR 山手線) 品川 発
8:58 (JR 山手線) 五反田 着

飛行機と新幹線の比較は本当に難しい。どちらも一長一短ではある。飛行機の方が東京への到着時間は遅れるものの、移動時間の関係で朝1時間ほど遅く出発できる分の身体的な負担が小さい。行きの方が元気があるので移動や待ち時間が少しあってもそれほど気にならない。飛行機は新幹線と比べて遅れる可能性があることだけ懸念でもある。今回は逆に5分早く着いたので余裕をもって移動できた。身体的な負担だけ考えれば、行きを飛行機、帰りを新幹線のルートで出張する方がよいようには思える。今回で飛行機のルートをだいぶ開拓できた。来月もこのルートで出張してみる。

同期飲みにおける失敗

お仕事を終えてから昔の同期と飲みに行った。寝てなくて疲れていたせいか、たくさん失敗したのを書いておく。以前に 公正証書の正本を紛失 する失敗と同じレベルで大失敗した。他人の失敗に対して寛容になること。自己の非を省みるために書いておく。

  • 友だちと待ち合わせの駅を間違う
    • 乗車時間が3分であったために二駅隣を一駅隣だと勘違いしてしまった
  • お土産に持っていったお酒を落として割ってしまう
    • もっていた紙袋の底が抜けてしまった
      • 紙袋ののりが劣化していた?
  • 酔っ払ってスマホで改札を通ろうとしてしまった

選挙後のやり取り

今日のバドミントン練習は、みなとのもり公園でジョギング4周強 (1.9km)、縄跳び (14:02) で1901回してからメイビス2で壁打ちを15分した。21時過ぎに帰ってきたのでビルの照明が1段階おちてて暗かったものの、壁打ちできないほどでもなかった。壁打ちは気持ち続く回数が増えた。しばらくは10回を目標に続ける。たまに同じ位置へ打ち返すことをキープして4-5回続けられる。バック持ちの方が得意になる。縄跳びで1900回を超えたのは過去最高になる。数回ミスと2回休憩して58秒のインターバル。1回休憩のミスを3回未満まで減らせば2000回を越せるかもしれない。それができるようになったら持久力がついたとみなして15分からさらに時間を増やそうと思う。

整合性の問題に関する検証を完了

金曜日の続き 。修正は完了していたのであとはテスト環境で実際の id 連携をやりながらサービスを停止したり開始したりしながらデータが失われないことを検証した。エントリー削除時の振る舞いを勘違いしていてはまったものの、それ以外のところは意図した通りに動いていて問題なかった。db と mq を併用したシステムにおける整合性に関する学びを得て今後の開発につなげる。

兵庫県知事選挙のふりかえり

昨日の 【開票結果】兵庫県知事選 失職の斎藤前知事が2回目の当選 の結果について知人とやり取りしていた。sns をうまく活用したさいとうさんが選挙前の劣勢を覆して大逆転するという、劇的な結果となった。

私がオンラインで調べた記事を読んだ限りでは、さいとうさんは前知事の残した負債を整理したり、OB の天下りを制限したり、既得権益に切り込むことを多々行っていて、関係者によるとそれらをよく思っていない人たちはたくさんいる模様。県民にとってはよいことではある。ハラスメントの度合いはよくわからないが、さいとうさんが知事を失職するほどの問題については次の疑惑次第だと思われる。

知人とやり取りしていての結論としては、第3者委員会や百条委員会の結果が出る前に県議会が不信任決議を全会一致にしてしまったために疑惑が曖昧な状態で県知事選挙が行われてしまった。さいとうさんに関しては思惑だけの世論となり、今回のような結果になったと思われる。疑惑の段階なのでさいとうさんが知事の資質に問題があるのか、既得権益からはめられたのかは現時点では県民には判断がつかない。にも関わらず、知事選挙をしてしまったがために sns のよくわからない情報で県民が判断して投票せざるを得なくなったという状況があるように思える。

立花さんのやっていることは私からみたら行き過ぎで告発者のプライベートの内容を暴露した。この問題が不倫であったがために告発者を信頼できないといった風潮が生まれた。そして、この情報を隠していた人たちが悪意をもっている、または隠蔽してさいとうさんを貶めようとしたと主張している。告発者は7月7日に自殺したが、そのときに差し押さえされたパソコン内に不倫に関する情報が残っていて、その内容を百条委員会で暴露されることを気にして告発者が自殺したというのが背景だと考えられている。

この告発者のプライベートな内容の中身を知っていた議員とそうじゃない議員がいたようにみえる。維新系議員が自殺した後も公開すべきだと主張し、その情報がリークされて週刊誌が報じ、維新系議員への批判が高まり、プライベートな内容は非開示と百条委員会で決定された。

奥谷さんは7月時点で非開示だと委員会で決定していたこと。そしてその中身は知らなかったが、それが自殺するほどの要因になっていることは把握していたことから委員長としてその情報を暴露しないように気を使っていたということを証言している。7月時点でも告発者の自殺の原因は知事によるハラスメントではなく、プライベートな内容を開示することへの懸念であることが記事に書かれている。もちろんその内容までは書かれていない。

プライバシー情報については、情報公開条例において『個人のプライバシーは最大限配慮する』と定められていること『元県民局長の代理人からプライバシーに関する取扱いの申し入れ』があったことなどから、百条委員会ではことし7月に私的情報に配慮することが決まっていました。

「脅して『自死』しても困る」立花氏に脅されたと百条委の奥谷氏 「ネットの暴力。家族狂乱」辞職の議員

しかし、10月末に片山副知事がそのプライベートな内容を発言しようとして奥山さんはその発言を遮ってやめさせた。奥山さんは委員会での決定事項を遵守しようとしただけだが、立花さんは既得権益層が政治的に悪意をもって告発者に不利な内容を隠蔽したと主張して、選挙のときの雰囲気ではその暴露によって委員会側の悪意があったかのように受け取る人たちも多かったようにみえる。もちろん事実関係としてどちらが正しいかはわからない。しかし、今回の内部告発文書問題はさまざまな政治的思惑が入り乱れているのでかなりややこしい。県議会もお互いの会派が情報をリークしているようにみえるのでどちらか一方が悪いとも言い切れない。

そんなことを夜中の3時まで調べたりしていて出張前なのにほとんど寝れなかった。

壁打ちとシャトル

今日のバドミントン練習は壁打ちを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 とメッセージを扱うときはこの経験を活かすためにふりかえりとして書いておく。