GitLab Events Platform
| Status | Authors | Coach | DRIs | Owning Stage | Created |
|---|---|---|---|---|---|
| proposed | @grzesiek, @fabiopitino | @ayufan | @jreporter, @sgoldstein | ~devops::ops section | 2023-03-06 |
概要
GitLab のコードベースは、2011 年の最初のコミット以来大きく成長しました。何百万ものユーザーに採用された多くの機能を実装してきました。さらなる機能への需要がある一方で、パラダイムシフトの機会もあります。特定のユースケースをカバーする機能を提供する代わりに、ユーザーが必要に応じて自動化で拡張できるプラットフォームの構築を始めることができます。堅牢なイベントシステムを使用して外部および内部ワークフローと統合できる、柔軟でジェネリックな DevSecOps ソリューションを構築できます。
この設計ドキュメントでは、以下を可能にするために追加の抽象化レイヤーをいくつか加えることを提案します:
- イベントの起源とスキーマをエンコードするイベント階層の概念を設計する。
- Publishers を使用してアプリケーションコード内からイベントを発行する。
- Gateways を使用して外部ソースからのイベントを傍受・変換する。
- Subscribers を使用して内部・外部イベントをサブスクライブする。
- キューイングと処理の実装詳細を抽象化の背後に隠蔽する。
これにより、GitLab を汎用の自動化ツールに変換できるだけでなく、既存のイベント系機能の複雑さも軽減できます:
ゴール
内部および外部で発行されるイベントをより適切に管理するために必要な抽象化とその実装を構築します。
課題
- ユーザーがサブスクライバーとパブリッシャーを構築できるソリューションが存在しない。
- Ruby コード外でサブスクリプションを管理するソリューションが存在しない。
- GitLab 内に共通の抽象化を使用しない多くのイベント系機能が存在する。
- 現在のイベントソリューション
Gitlab::EventStoreは Sidekiq と密結合している。 - 外部から発行されたイベントをサブスクライブするための統一された堅牢な方法が存在しない。
- イベントに関連するペイロードは、スキーマの定義方法と同様に大きく異なる。
- すべてのイベントが強く型付けされているわけではなく、その階層を管理するソリューションが存在しない。
- イベントはバージョン管理されておらず、スキーマコントラクトを破壊しやすい。
- イベントに基づいた機能をより多く構築したいが、抽象化が欠如しているため、実装から得られる価値が限られる。
提案
Publishers
Rails コードベース内からイベントを発行することは、提案するアーキテクチャの重要な要素です。イベントは、理想的には Ruby クラスを使用して強く型付けされるべきです。
例えば、以下の方法でイベントを発行できます:
include Gitlab::Events::Emittable
emit Gitlab::Events::Package::Published.new(package)
- イベントの発行はノンブロッキングで、ほぼゼロコストの操作であるべきです。
- イベントの発行は、その起源とアイデンティティを考慮に入れるべきです。
- イベントの発行は、系譜に基づいてペイロードを構築するべきです。
emitはGitLab::EventStoreで使用されるメカニズムの糖衣構文にできます。
Subscribers
Subscribers により、アプリケーション開発者は内部または外部で発行された任意のイベントをサブスクライブできます。また、Subscribers はアプリケーション開発者が、例えばプロジェクトイベントをサブスクライブしてパイプラインをトリガーするために、ユーザーが使用できるサブスクリプションメカニズムを構築できるようにもします。
Subscribers がサブスクライブするイベントはコントラクトとなるため、バージョン管理するか、前方・後方互換性のあるソリューション(Protobuf など)を使用するべきです。
Gateways
Gateways は内部および外部のイベントを傍受し、型を変更し、系譜を補強し、ペイロードを変換するために使用できます。
Gateways は例えば、Cloud Events を傍受するシンクエンドポイントを実装し、内部で使用される Ruby クラスにラップして、開発者・ユーザーがサブスクライブできるようにするために使用できます。
また、Gateways を使用して実装されたジェネリックなイベントバスを通じて、クロスCell 通信を実装できるかもしれません。
複数のインスタンスを含む複雑なデプロイメントの調整方法を改善するためのクロスインスタンス通信に関するアイデアもあります。
処理
現在、イベントをキューイングするために PostgreSQL または Sidekiq を使用しています。どちらのメカニズムも互換的に使用されており、既存のソリューションと密結合しています。
キューイングと処理の抽象化を構築する主な目的は、必要に応じて異なるキューイングバックエンドに切り替えられるようにすることです。例えば、一部のイベントを Google Pub/Sub にキューイングし、専用の Gateway を経由してアプリケーションに戻すことができます。
可観測性
イベント、パブリッシャー、サブスクライバー間の相互作用を理解するために、OpenTelemetry を経由した適切なインストルメンテーションを提供する必要があるかもしれません。これにより、分散トレーシングバックエンドを使用してこれらの相互作用を視覚化できるようになります。
