このドキュメントでは、Bedrudのシングルバイナリアーキテクチャの背後にある内部技術的判断について説明します。
1. Fiberから標準ライブラリへのブリッジ
Bedrudは速度のためにFiberを使用していますが、Goth(OAuth)やLiveKit SDK(Twirp)などの一部の依存関係は標準Goのhttp.ResponseWriterとhttp.Requestを必要とします。
これら2つの世界を橋渡しするため、Bedrudはinternal/handlers/auth.goでアダプタパターンを実装しています:
responseWriterアダプタ
type responseWriter struct {
ctx *fiber.Ctx
headers http.Header
status int
}この構造体はhttp.ResponseWriterインターフェースを実装しています。標準ライブラリ関数(Gothなど)がHeader().Add()を呼び出すと、アダプタはローカルのheadersマップに保存します。WriteHeader()が呼び出されると、すべてのヘッダーをFiberコンテキストに手動でコピーし戻します。
目的
Bedrudは極めて高速なまま(Fiberを使用)、標準Goウェブライブラリの広大なエコシステムとの完全な互換性を維持できます。
2. LiveKitリバースプロキシ
Bedrudはメインポート経由ですべてのメディアシグナリングをルーティングすることで、ポート管理の問題を回避しています。
仕組み:
- 検出:
LIVEKIT_INTERNAL_HOSTが127.0.0.1を指している場合、Bedrudは内部メディアエンジンを起動します。 - マウント:
/livekitルートにhttputil.NewSingleHostReverseProxyをマウントします。 - パスストリッピング: カスタムDirector関数を使用して
/livekitプレフィックスを削除し、メディアサーバーがルートにリクエストが来たかのように受け取れるようにします。 - WebSocketサポート: プロキシは
adaptor.HTTPHandlerを経由して基盤のTCPストリーム上で動作するため、LiveKitがリアルタイムシグナリングに使用するWebSocketsをネイティブにサポートします。
3. ストレージ効率: 埋め込み構造体
BedrudはGORMのembeddedタグを活用して、データベーススキーマをフラットかつ最適化された状態に保っています。
models/room.goの例:
type Room struct {
ID string `gorm:"primaryKey"`
Settings RoomSettings `gorm:"embedded;embeddedPrefix:settings_"`
}これにより、GORMはsettings_allow_chatのようなカラムをroomsテーブルに直接作成します。これはJOINよりも高速で、JSONブロブよりも検索性に優れています。
4. テストインフラストラクチャ
Bedrudはinternal/testutilパッケージを使用した「DB-First」テスト戦略に従っています。
SetupTestDBの仕組み:
- 各テストごとに固有のSQLiteインメモリデータベースを作成します。
- すべてのマイグレーションを自動的に実行します。
- クリーンな状態を提供し、テストが決定論的で並列実行可能であることを保証します。
バックエンドテストを実行するには:
go test ./internal/...5. セキュリティ: トークンローテーションと失効
シンプルなJWT実装とは異なり、Bedrudは更新のたびに両方のトークンをローテーションします。
- リフレッシュトークンの再利用検出: リフレッシュトークンが新しいペアの取得に使用されると、直ちにブロックされます。
- クリーンアップ:
BlockedRefreshTokenテーブルにより、リフレッシュトークンが盗まれた場合でも、ユーザーが正常にログアウトまたはセッションを更新した後は使用できなくなります。