古くなったレプリカの復旧

Sync Framework は、変更を適用する前に、同期元レプリカの忘れられたナレッジと同期先レプリカの現在のナレッジを比較します。同期先ナレッジに忘れられたナレッジが含まれていない場合、Sync Framework は同期先レプリカが古くなっていると判断し、復旧同期を開始します。

復旧同期を実行するために、Sync Framework では次の手順が実行されます。

  • アプリケーションが通知を受け取るように登録されている場合、Sync Framework は、復旧同期が必要なことをアプリケーションに通知します。アプリケーションでは、同期元レプリカのすべての項目を完全に列挙するか、部分的な同期を実行するか、同期を取り消すことができます。既定では、同期が取り消されます。

  • アプリケーションで完全な列挙処理が指定されている場合、Sync Framework は現在の変更バッチを破棄し、同期元レプリカのすべての項目を完全に列挙して同期先レプリカに適用します。

  • アプリケーションで部分的な同期が指定されている場合、Sync Framework は通常の同期と同様に、同期元の変更を列挙して同期先レプリカに適用します。ただし、学習したナレッジに対する変更は、1 つの項目の例外として適用されます。

復旧同期について

Sync Framework の同期コミュニティ内の各レプリカには、レプリカ内の項目に関するメタデータが保持されます。メタデータによって、レプリカに格納される項目の作成、変更、および削除に関する情報が追跡されます。通常、記憶領域が不足するのを回避するために、レプリカで削除済み項目のメタデータを定期的にクリーンアップする必要があります。レプリカで削除済み項目のメタデータが削除されると、同期中に削除を列挙して変更として送信することができなくなります。同期コミュニティ内のすべてのレプリカで、メタデータをクリーンアップする前に削除を同期すれば、すべての削除が正しく伝達され、問題は発生しません。

一方、他のレプリカでメタデータのクリーンアップが実行されるまでデータを同期しない場合、レプリカは古くなることがあります。この場合、クリーンアップを実行したレプリカはクリーンアップされた変更を列挙できなくなるので、古くなったレプリカにその変更を送信することはできません。この問題を解決するために、Sync Framework では、メタデータのクリーンアップを実行した同期元レプリカと古くなった同期先レプリカの間で同期を試行する際に、復旧同期を使用して同期先レプリカを復元する必要があります。復旧同期は、同期コミュニティから削除された項目が、古くなったレプリカで再挿入されるのを防ぐために必要です。

Sync Framework は、同期元レプリカの忘れられたナレッジを使用して、同期先レプリカが古くなったことを検出します。レプリカで削除済み項目のメタデータが削除されるときに、レプリカの忘れられたナレッジに削除のバージョンが記録されます。これで、忘れられたナレッジを使用して、レプリカが把握していた項目、削除された項目、およびメタデータが削除された項目を識別できるようになります。忘れられたナレッジには、メタデータが 1 つでも削除された項目がすべて含まれることに注意してください。したがって、忘れられたナレッジには、メタデータにアクティブなエントリが残っている項目も含まれている可能性があります。

復旧同期の通知への応答

アプリケーションでは、復旧同期が必要であるという通知を受け取るための登録を行うことができます。アプリケーションは、この通知を捕捉することにより、完全な列挙処理を開始するか、現在のセッションを続行するか、セッションを中止するかを必要に応じて制御できます。アプリケーションがこの通知を受け取るように登録されていない場合、既定では、Sync Framework はセッションを停止します。

マネージ コードを使用した復旧同期の通知への応答

復旧同期が必要であるという通知を受け取るには、アプリケーションでイベント ハンドラーを実装し、FullEnumerationNeeded イベントを受信するためにそのハンドラーを登録します。このイベントが発生すると、FullEnumerationNeededEventArgs オブジェクトの Action プロパティを設定することによって、イベント ハンドラーが応答して次のいずれかの操作が実行されます。

  • Full を指定すると、Sync Framework は次のメソッドを呼び出し、現在の変更バッチを破棄して完全な列挙処理を開始します。

  • Partial を指定すると、Sync Framework は通常の同期と同様に、現在の変更バッチを適用してセッションを続行します。ただし、学習したナレッジに対する変更はすべて、1 つの項目の例外として適用されます。1 つの項目の例外は通常のナレッジの表現よりも効率が悪いので、完全な列挙をすぐに実行できない場合にのみ部分的な同期を行うようにしてください。Sync Framework は、完全な列挙が実行されるまで、各同期の開始時に完全な列挙の実行を要求し続けます。

  • Abort を指定すると、現在のセッションが中止されます。

アンマネージ コードを使用した復旧同期の通知への応答

復旧同期が必要であるという通知を受け取るには、アプリケーションで ISyncCallback インターフェイスを実装し、ISyncSession::RegisterCallback を使用してそのインターフェイスを登録します。復旧同期の開始前に、Sync Framework によって ISyncCallback::OnFullEnumerationNeeded が呼び出されます。このメソッドは、次のいずれかの操作を返します。

  • SFEA_FULL_ENUMERATION を指定すると、Sync Framework は次のメソッドを呼び出し、現在の変更バッチを破棄して完全な列挙処理を開始します。

  • SFEA_PARTIAL_SYNC を指定すると、Sync Framework は通常の同期と同様に、現在の変更バッチを適用してセッションを続行します。ただし、学習したナレッジに対する変更はすべて、1 つの項目の例外として適用されます。1 つの項目の例外は通常のナレッジの表現よりも効率が悪いので、完全な列挙をすぐに実行できない場合にのみ部分的な同期を行うようにしてください。Sync Framework は、完全な列挙が実行されるまで、各同期の開始時に完全な列挙の実行を要求し続けます。

  • SFEA_ABORT を指定すると、現在のセッションが中止されます。

同期元レプリカのすべての変更の完全な列挙

Sync Framework では、完全な列挙処理中に、同期元プロバイダーがすべての変更を列挙する必要があります。その後、Sync Framework で、同期元プロバイダーからの変更と同期先レプリカの項目が比較されます。同期元プロバイダーからの対応する変更が含まれていない同期先レプリカの項目は、同期元レプリカから削除されたと見なされ、同期先レプリカから削除されます。このため、同期元プロバイダーによって同期元レプリカのすべての項目が正しく列挙されていることを確認してください。正しく列挙されないと、項目が同期先レプリカから誤って削除されます。

マネージ コードを使用した変更の完全な列挙

同期元プロバイダーの変更を完全に列挙するために、Sync Framework は GetChangeBatch ではなく GetFullEnumerationChangeBatch を呼び出します。このメソッドが呼び出されると、同期元プロバイダーから FullEnumerationChangeBatch オブジェクトが返されます。この変更バッチを作成するには、次の手順に従います。

  1. BeginOrderedGroup を使用して、順序付けられているグループを開きます。グループの開始に使用される項目 ID は、列挙される最初の ID である必要があり、GetFullEnumerationChangeBatch で指定した列挙の下限以下である必要もあります。

  2. オプションで、同期先ナレッジに含まれていない、項目 ID が列挙の下限より小さい変更を、項目 ID の順にバッチに追加します。

  3. 項目 ID が列挙の下限以上の変更を、項目 ID の順にバッチに追加します。

  4. EndOrderedGroup を使用して、順序付けられているグループを閉じます。列挙の上限を、グループに最後に追加された変更の ID として指定します。これが最後のバッチである場合は、列挙の上限を Infinity として指定します。

  5. これが最後のバッチである場合は、SetLastBatch を呼び出します。最後のバッチではない場合は、Sync Framework によって GetFullEnumerationChangeBatch が再度呼び出されます。

アンマネージ コードを使用した変更の完全な列挙

同期元プロバイダーの変更を完全に列挙するために、Sync Framework は IKnowledgeSyncProvider::GetChangeBatch ではなく IKnowledgeSyncProvider::GetFullEnumerationChangeBatch を呼び出します。このメソッドが呼び出されると、同期元プロバイダーから ISyncFullEnumerationChangeBatch オブジェクトが返されます。この変更バッチを作成するには、次の手順に従います。

  1. IProviderSyncServices::CreateFullEnumerationChangeBatch を使用して、変更バッチ オブジェクトを作成します。

  2. ISyncChangeBatchBase::BeginOrderedGroup を使用して、順序付けられているグループを開きます。グループの開始に使用される項目 ID は、列挙される最初の ID である必要があり、GetFullEnumerationChangeBatch で指定した列挙の下限以下である必要もあります。

  3. オプションで、同期先ナレッジに含まれていない、項目 ID が列挙の下限より小さい変更を、項目 ID の順にバッチに追加します。

  4. 項目 ID が列挙の下限以上の変更を、項目 ID の順にバッチに追加します。

  5. ISyncChangeBatchBase::EndOrderedGroup を使用して、順序付けられているグループを閉じます。列挙の上限を、グループに最後に追加された変更の ID として指定します。これが最後のバッチである場合は、列挙の上限を NULL として指定します。

  6. これが最後のバッチである場合は、ISyncChangeBatchBase::SetLastBatch を呼び出します。最後のバッチではない場合は、Sync Framework によって GetFullEnumerationChangeBatch が再度呼び出されます。

復旧同期中の変更の処理

同期先レプリカから削除する項目を判断するために、Sync Framework では、項目 ID が各変更バッチの列挙の上限と下限の範囲内にある同期先レプリカのすべての項目を、同期先プロバイダーが項目 ID の順に列挙する必要があります。同期元プロバイダーから列挙された対応する変更が含まれていない同期先レプリカの項目は削除されます。

同期先プロバイダーは、この同期先の項目一覧を変更適用元に渡します。変更適用元は各変更の処理方法を決定し、適切な同期先プロバイダーのメソッドを呼び出して変更を同期先レプリカに適用します。

マネージ コードを使用した変更の処理

復旧同期中に変更を処理するために、Sync Framework は同期先プロバイダーの ProcessFullEnumerationChangeBatch メソッドを呼び出します。このメソッドは、同期元プロバイダーからの変更を含む FullEnumerationChangeBatch オブジェクトを提供します。

同期先プロバイダーで Sync Framework の NotifyingChangeApplier オブジェクトを使用する場合、同期先プロバイダーは ApplyFullEnumerationChanges メソッドを呼び出して変更を適用する必要があります。このメソッドでは、項目 ID が同期元の変更バッチの DestinationVersionEnumerationRangeLowerBound プロパティと DestinationVersionEnumerationRangeUpperBound プロパティの間にある、同期先のすべての変更を項目 ID の順に並べ替えたコレクションが必要です。変更を適用するために、NotifyingChangeApplier オブジェクトが通常の同期と同様に INotifyingChangeApplierTarget メソッドを呼び出します。

アンマネージ コードを使用した変更の処理

復旧同期中に変更を処理するために、Sync Framework は同期先プロバイダーの IKnowledgeSyncProvider::ProcessFullEnumerationChangeBatch メソッドを呼び出します。このメソッドは、同期元プロバイダーからの変更を含む ISyncFullEnumerationChangeBatch オブジェクトを提供します。

同期先プロバイダーで Sync Framework の ISynchronousNotifyingChangeApplier オブジェクトを使用する場合、同期先プロバイダーは ISynchronousNotifyingChangeApplier::ApplyFullEnumerationChanges メソッドを呼び出して変更を適用する必要があります。このメソッドでは、項目 ID が同期元の変更バッチの ISyncFullEnumerationChangeBatch::GetClosedLowerBoundItemId プロパティと ISyncFullEnumerationChangeBatch::GetClosedUpperBoundItemId プロパティの間にある、同期先のすべての変更を項目 ID の順に並べ替えたコレクションが必要です。変更を適用するために、ISynchronousNotifyingChangeApplier オブジェクトが通常の同期と同様に ISynchronousNotifyingChangeApplierTarget インターフェイス メソッドを呼び出します。

参照

概念

標準のカスタム プロバイダーの実装
変更の列挙
変更の適用