このドキュメントはAIによって翻訳されました。不正確な情報については、英語版をご参照ください
シングルノード環境では、プラグインは通常、プロセス内の状態、イベント、またはタスクを通じて要件を満たすことができます。しかし、クラスターモードでは、同じプラグインが複数のインスタンスで同時に実行される可能性があり、以下のような典型的な課題に直面します。
NocoBase のコアは、アプリケーション層に様々なミドルウェアインターフェースをプリセットしています。これにより、プラグインがクラスター環境で共通の機能を再利用できるようになります。以下では、キャッシュ、同期メッセージ、メッセージキュー、分散ロックの利用方法とベストプラクティスを、ソースコードと合わせてご紹介します。
メモリに保存する必要があるデータには、システムに組み込まれているキャッシュコンポーネントを使用することをお勧めします。
app.cache を介してデフォルトのキャッシュインスタンスを取得します。Cache は set/get/del/reset といった基本的な操作を提供します。また、キャッシュロジックをカプセル化するための wrap や wrapWithCondition、そして mset/mget/mdel のようなバッチメソッドもサポートしています。ttl を設定することをお勧めします。例:plugin-auth におけるキャッシュの初期化と使用
メモリ内の状態が分散キャッシュで管理できない場合(例えば、シリアライズできない場合)、ユーザー操作によって状態が変化した際には、その変化を同期シグナルを通じて他のインスタンスに通知し、状態の一貫性を保つ必要があります。
sendSyncMessage が実装されており、内部で app.syncMessageManager.publish を呼び出し、チャネルにアプリケーションレベルのプレフィックスを自動で追加することで、チャネルの衝突を防ぎます。publish では transaction を指定でき、メッセージはデータベーストランザクションがコミットされた後に送信されるため、状態とメッセージの同期が保証されます。handleSyncMessage を通じて他のインスタンスから送信されたメッセージを処理します。beforeLoad フェーズで購読することができ、設定変更やスキーマ同期などのシナリオに非常に適しています。例:plugin-data-source-main が同期メッセージを使用して複数ノード間のスキーマ一貫性を維持する
メッセージブロードキャストは同期シグナルの基盤となるコンポーネントであり、直接使用することも可能です。インスタンス間でメッセージをブロードキャストする必要がある場合に、このコンポーネントを利用できます。
app.pubSubManager.subscribe(channel, handler, { debounce }) を使用してインスタンス間でチャネルを購読できます。debounce オプションは、重複ブロードキャストによる頻繁なコールバックを防ぐためのデバウンス処理に使用されます。publish は skipSelf(デフォルトは true)と onlySelf をサポートしており、メッセージが現在のインスタンスに送り返されるかどうかを制御します。例:plugin-async-task-manager が PubSub を使用してタスクキャンセルイベントをブロードキャストする
メッセージキューは非同期タスクのスケジューリングに使用され、時間のかかる操作や再試行可能な操作の処理に適しています。
app.eventQueue.subscribe(channel, { idle, process, concurrency }) を介してコンシューマーを宣言します。process は Promise を返し、AbortSignal.timeout を使用してタイムアウトを制御できます。publish はアプリケーション名のプレフィックスを自動で補完し、timeout や maxRetries などのオプションをサポートしています。デフォルトではインメモリキューアダプターが使用されますが、必要に応じて RabbitMQ などの拡張アダプターに切り替えることができます。例:plugin-async-task-manager が EventQueue を使用してタスクをスケジューリングする
競合操作を避ける必要がある場合、分散ロックを使用してリソースへのアクセスをシーケンシャルに処理できます。
local アダプターが提供されており、Redisなどの分散実装を登録できます。app.lockManager.runExclusive(key, fn, ttl) または acquire/tryAcquire を介して並行処理を制御します。ttl は、異常な状況でロックが永久に保持されるのを防ぐためのフォールバックとして、ロックを解放するために使用されます。例:plugin-data-source-main が分散ロックを使用してフィールド削除プロセスを保護する
app.cache や app.syncMessageManager などの機能を統一的に使用し、プラグイン内でノード間通信ロジックを重複して実装するのを避けてください。transaction.afterCommit(syncMessageManager.publish には組み込み済み)を使用すべきです。timeout、maxRetries、debounce を適切に設定してください。これらの機能を利用することで、プラグインは異なるインスタンス間で安全に状態を共有し、設定を同期し、タスクをスケジューリングできるようになり、クラスターデプロイメントシナリオにおける安定性と一貫性の要件を満たします。