なかなか開発がテンパっているものの、今日でようやく一通りのリファクタリングを完了して、意図していた新機能のための web api が動くところまで確認できた。なんというか、新機能を作るために既存コードの改善に8割の時間を費やした感じ。おかげで新機能はなにも開発していないのに勝手に動いた (違) ような気持ちになった。今後、同様に個別データの拡張や新たなデータ追加のときは既存データに影響を与えず、独立して追加しやすい設計となっている。将来的に私がいなくなった後に拡張するときにこの設計は役に立つだろうと思う。
awesome-go へ道
昨日の続き 。contribution guidelines を読んでいて最低限やれと書いてあることの1つに Go Report Card report を作れと書いてあった。これは静的解析したスコアのようなものが表示される。すべて100%が表示されるようにした。
if the library/program is testable, then coverage should be >= 80% for non-data-related packages and >=90% for data-related packages. (Note: the tests will be reviewed too. We will check your coverage manually if your package’s coverage is just a benchmark result);
特定の path 配下の web api にミドルウェアで認証や認可を適用している。こうしておけば認証しなければいけない web api の認証設定を実装し忘れるということが絶対に起きない。一方で未認証の web api もある。/auth/login や /status/ping といったものだ。これらは未認証で呼び出せるのでトップレベルの path をわけたい。そうすると、既存のトップレベルに設定してある /api/xxx という名前が論理的におかしい。web api は他にもあるのに認証を要するものだけ api というトップレベルの path を付けるのは奇妙に思えてくる。
ツールを使ってテストしていて、成功するはずのリクエストが失敗して、ログを調査しながらデバッグしていた。ldap エントリーを扱う難しさの1つに、ldap サーバーはエントリー間の依存関係やデータの整合性といったものを検証しない。そういった用途はアプリケーションの役割であって、ldap プロトコルはあくまで id を管理することに特化したものという役割分担になっているのだと推測する。そうすると、(open) ldap サーバーへ登録できたエントリーが次の agent や api サーバーといったアプリケーションのレイヤーでエラーになることがある。このとき、ldap サーバーではエラーが発生していないため、直接的なエラーを検知することができなくて、デバッグや調査に時間がかかる。
agent の実装として、ユーザーエントリのストリームとグループエントリーのストリームの2つに分割して、非同期にそれぞれのエントリーを id 連携する設計にしていた。というのは、ldap エントリーにはユーザーやグループといった概念は原則として存在しない。そのエントリーがユーザーなのか、グループなのかはアプリケーションが判断している。アプリケーションの用途としてはこの2つを明確にわけないと不便なことから、ワークアラウンドもしくは実務的な解決策として検索するときのフィルターと base dn で管理するようにしていた。そして、これらをそれぞれ別のストリームとして扱うよう、私が設計していた。このことがタイミングによってはユーザーエントリーとグループエントリーに依存関係がある場合、データの整合性を保証できないことに気付いた。なぜならば、ユーザーエントリーとグループエントリーそれぞれ非同期/並行に処理されてしまうから。
typeRequeststruct {
...// ctx is either the client or server context. It should only
// be modified via copying the whole Request using Clone or WithContext.
// It is unexported to prevent people from using Context wrong
// and mutating the contexts held by callers of the same request.
ctxcontext.Context...}