Lock about update process

   
Status accepted

Context

  • 同じオブジェクトに対する更新系のエンドポイントが同時に実行された場合、多くの問題が発生する
    • 両方処理された場合、あとに終了する操作のみがDBに反映され、実体が二つ存在することになる
    • 一貫性がないため、同じIPがスケジューリングされたりする
  • 一貫性と整合性を保証する必要がある
    • TODO: どの強さのものなのかは少し勉強してからかく

Decision

  • github.com/n0stack/n0stack/n0core/pkg/datastore/lock に実装を行った
  • apiは更新系のエンドポイント開始時に Datastore.Lock(key string) をかける
    • ロックをかけることで一貫性を保証
    • ロックがかかっていないものはdatastoreの更新系を実行できないようにブロック
      • 実装の間違いに気づきやすいようにした
        • panicにしても良さそう?
    • ロックに失敗した場合即時返していたが、 ReserveStorage などのエンドポイントのエラーレートが非常に高くなってしまったので、ロックがかかるまで一定時間リトライするものを実装した
      • Createはロックできない時点で他の人が作っているはずで、ユーザーの不備なはずなのですぐ返す
      • Deleteは少し危険な気がするので安全側に倒すなら待たない
      • 拡張メソッドは基本的に他のユーザーがロックをかけている可能性があるので、待つ
  • 参照系に関しては制約をかけていない
    • 高いパフォーマンスが優先されると考えたため
    • 少し古いデータを見せられても致命的な問題が起こるとは考えにくい
  • DBの機能を使わなかった理由は、今後n0core以外のデーモンを消していくつもりであるため
    • n0coreはすべての起点であるため、依存を可能な限り減らしたい

Consequences

  • 適宜更新

Reference

  • #115