クライアントのリセット - .NET SDK
項目一覧
Overview
バージョン 10.17.0 の新機能。
クライアント リセット エラーとは、クライアント邦土がアプリケーション バックエンドとデータを同期できないシナリオです。 この状態のクライアントは引き続きデータを実行してローカルに保存できますが、クライアントがリセットされるまで同期の変更セットを送信または受信することはできません。 Realm SDK は、ほとんどのシナリオでクライアントのリセットを自動的に処理するメソッドを提供します。
クライアントリセット戦略
クライアント リセット シナリオは、サーバーの履歴がクライアントの履歴と互換性がない場合に発生します。 クライアント リセットの最も一般的な原因は、「 クライアントのリセット 」で説明されています。
.NET SDK では、 FlexibleSyncConfigurationとpartitionSyncConfigurationでクライアント リセット戦略を指定できます。 ClientResetHandlerプロパティは、次のいずれかに設定できます。
Handler | 戦略 | ノート |
---|---|---|
同期されていないすべてのローカル変更を回復する | 復元に失敗した場合、このハンドラーは DiscardUnsyncedChangesHandler にフォールバックし、同期されていないローカル変更をすべて削除します。 DiscardUnsyncedChangesHandler の復元が失敗した場合、ハンドラーはManualRecoveryHandler にフォールバックします。その場合は、手動による復元戦略を実装する必要があります。 | |
同期されていないすべてのローカル変更を回復する | 復元に失敗した場合、このハンドラーは ManualRecoveryHandler にフォールバックします。その場合は、手動復元戦略を実装する必要があります。 | |
同期されていない変更を破棄する | この戦略では、最後の同期が成功した以降に行われたすべてのローカルの同期されていない変更を永続的に削除します。 | |
手動リカバリ | 独自のリカバリ戦略を実装する方法を提供します。 |
次のセクションでは、クライアント リセットを処理するためのさまざまな戦略と、それぞれのClientResetHandlers
の使用方法について説明します。
同期されていないローカル変更の回復
スキーマの重大な変更を伴うクライアント リセットでは、SDK は、クライアントがリセットされる前に同期されなかったローカルで作成されたオブジェクトを統合します。 バックエンドとクライアントの両方が同じオブジェクトに変更を加える場合に競合を解決する方法は、次のルールによって決まります。
オブジェクトがサーバー上で削除されたが、復元されたクライアントで変更された場合は、削除が優先され、クライアントは更新を破棄します。
リカバリ クライアントでオブジェクトが削除されたが、サーバーでは削除された場合、クライアントは削除指示を適用します。
同じフィールドへの更新が競合する場合は、クライアント更新が適用されます。
重要
重大な変更
リカバリ プロセスでは、スキーマの重大な変更は処理できません。 たとえば、Realm オブジェクト クラスの 1 つ以上に追加的でない変更を加えると、回復プロセスは失敗します。 この場合、ユーザーはクライアント アプリを更新する必要があります。 重大な変更の詳細については、 重大な変更と重大でない変更のクイック リファレンス を参照してください。
同期されていないローカル データを自動的に回復しようとするクライアント リセット ハンドラーには、 RecoverOrDiscardUnsyncedChangesHandler
とRecoverUnsyncedChangesHandler
の 2 つがあります。
ReactiveOrDiscardUnsyncedchangesHandler
これは、最も堅牢なリカバリプロセスを提供するためのデフォルトのハンドラーです。 自動回復プロセスが失敗した場合は、「 同期されていない変更の破棄 」セクションで説明されているDiscardLocalReset
戦略に戻ります。 そのプロセスが失敗した場合は、「手動リカバリ セクション 」で説明されている手動リセット戦略に再度フォールバックします。 このハンドラーは、次のコールバック メソッドを提供します。
OnBeforeReset 。クライアントがリセットする前に SDK が呼び出します。 このコールバックを使用して、クライアントのリセットが開始される前にユーザーに通知できます。
OnAfterReactiveは、自動リセットが正常に完了した場合にのみ、SDK によって呼び出されます。 これを使用して、クライアントのリセットが完了したことをユーザーに通知できます。
OnAfterDiscard 。これは、自動クライアント リセットが失敗し、ローカル破棄戦略が成功した場合にのみ SDK が呼び出します。 破棄戦略が失敗した場合、このコールバックは呼び出されません。
ManualResetFallback 。SDKは、自動復元と破棄戦略が失敗した場合にのみ呼び出します。 リセットの失敗を処理するには、このコールバックを実装します。 ここでのロジックは、 ManualRecoveryHandler に説明されているロジックと同様です。
次の例では、これらのコールバックそれぞれの使用方法を示しています。
var conf = new FlexibleSyncConfiguration(user) { ClientResetHandler = new RecoverOrDiscardUnsyncedChangesHandler { // The following callbacks are optional OnBeforeReset = (beforeReset) => { // Executed before the client reset begins // Can be used to notify the user that a reset is going // to happen }, OnAfterRecovery = (beforeReset, afterReset) => { // Executed after the client reset is complete // Can be used to notify the user that the reset is done }, OnAfterDiscard = (beforeReset, afterReset) => { // Executed if the automatic recovery has failed // but the DiscardUnsyncedChanges fallback has completed // successfully }, ManualResetFallback = (err) => { // Automatic reset failed; handle the reset manually here } } };
ReactiveUnsyncedchangesHandler
RecoverOrDiscardUnsyncedChangesHandler
と同様に、このハンドラーは同期されていないすべてのローカル変更を自動的に回復しようとします。 ただし、 RecoverOrDiscardUnsyncedChangesHandler
とは異なり、このハンドラーは自動復元が失敗した場合でもDiscardUnsyncedChangesHandler
にフォールバックしません。 代わりに、「手動リカバリのセクション 」で説明されている手動リセット戦略に戻ります。 ハンドラーは次のコールバック メソッドを提供します。
OnBeforeReset 。リセットが開始される前にユーザーに通知するために使用できます。
OnAfterReset 。リセットが正常に完了したことをユーザーに通知するために使用できます。
ManualResetFallback 。リセットの失敗を処理するために実装します。 ここでのロジックは、 ManualRecoveryHandler に説明されているロジックと同様です。
次の例では、これらのコールバックそれぞれの使用方法を示しています。
var conf = new FlexibleSyncConfiguration(user) { ClientResetHandler = new RecoverUnsyncedChangesHandler { // The following callbacks are optional OnBeforeReset = (beforeReset) => { // Executed before the client reset begins // Can be used to notify the user that a reset is going // to happen }, OnAfterReset = (beforeReset, afterReset) => { // Executed after the client reset is complete // Can be used to notify the user that the reset is done }, ManualResetFallback = (err) => { // Automatic reset failed; handle the reset manually here } } };
同期されていない変更の破棄
この戦略では、最後の同期が成功した以降に行われたすべてのローカルの同期されていない変更を永続的に削除します。 DiscardUnsyncedChangesHandler
を使用する場合、SDK は Realm を閉じることなく、通知が完全に機能したままにローカル Realm ファイルを同期可能な状態に復元します。 このプロセスが失敗した場合は、「手動回復セクション 」で説明されている手動リセット戦略に戻ります。 このハンドラーは、次のコールバック メソッドを提供します。
OnBeforeReset 。クライアントがリセットする前に SDK が呼び出します。 このコールバックを使用して、リセットが開始される前にユーザーに通知できます。
OnAfterReset 。リセットが正常に完了した場合にのみ、SDK は呼び出します。 これを使用して、リセットが完了したときにユーザーに通知できます。
ManualResetFallback 。リセットが失敗した場合に SDK が呼び出します。 ここでのロジックは、 ManualRecoveryHandler に説明されているロジックと同様です。
次の例は、 DiscardUnsyncedChangesHandler
を実装する方法を示しています。
{
var config = new FlexibleSyncConfiguration(user);
config.ClientResetHandler = new DiscardUnsyncedChangesHandler()
{
// The following callbacks are optional
OnBeforeReset = (beforeReset) =>
{ // Executed before the client reset begins // Can be used to notify the user that a reset is going // to happen },
OnAfterReset = (beforeReset, afterReset) => { // Executed after the client reset is complete // Can be used to notify the user that the reset is done },
ManualResetFallback = (err) =>
{ // Automatic reset failed; handle the reset manually here }
};
try {
var realm = await Realm.GetInstanceAsync(config); }
catch (Exception ex) { Console.WriteLine($@"Error creating or opening the realm file. {ex.Message}"); }
手動リカバリ
ほとんどの場合、クライアント リセットには他の戦略のいずれかを使用する必要があります。 データ回復プロセスをカスタマイズする必要がある頻度の低いケースには、 ManualRecoveryHandlerハンドラーを選択します。
注意
フォールバック
手動戦略はエッジケースでのみ使用する必要がありますが、他のクライアント リセット ハンドラーは手動戦略に戻る可能性があります。 これらのハンドラーで使用するロジックは、ここで説明するロジックと同様です。
ManualRecoveryHandler
内で、既存の Realm を破棄し、 InitiateClientReset()メソッドを呼び出します。
次の例えはManualRecoveryHandler
の実装を示しています。
private void SetupRealm()
{
var config = new FlexibleSyncConfiguration(user);
config.ClientResetHandler =
new ManualRecoveryHandler(HandleClientResetError);
var realm = await Realm.GetInstanceAsync(config);
}
private void HandleClientResetError(ClientResetException clientResetException)
{
Console.WriteLine($"Client Reset requested: {clientResetException.Message}");
// Prompt user to perform a client reset immediately. If they don't,
// they won't receive any data from the server until they restart the app
// and all changes they make will be discarded when the app restarts.
var didUserConfirmReset = ShowUserAConfirmationDialog();
if (didUserConfirmReset)
{
// Close the Realm before doing the reset. It must be
// deleted as part of the reset.
fsRealm.Dispose();
// perform the client reset
var didReset = clientResetException.InitiateClientReset();
if (didReset)
{
// Navigate the user back to the main page or reopen the
// the Realm and reinitialize the current page
}
else
{
// Reset failed - notify user that they'll need to
// update the app
}
}
}
クライアント リセット処理をテストします
Device Sync を終了して再度有効にすることで、アプリケーションのクライアント リセット処理を手動でテストできます。
同期を終了して再度有効にすると、以前に同期に接続したことのあるクライアントは、クライアント リセットを実行するまで接続できなくなります。 同期を終了すると、クライアントが同期できるようにするメタデータがサーバーから削除されます。 クライアントは、サーバーから Realm の新しいコピーをダウンロードする必要があります。 サーバーはこれらのクライアントにクライアント リセット エラーを送信します。 したがって、同期を終了すると、クライアントのリセット条件がtriggerされます。
クライアント リセット処理をテストするには:
クライアント アプリケーションからデータを書き込み、同期されるまで待ちます。
Device Sync を終了して再度有効にします。
クライアント アプリを再度実行します。 アプリは、サーバーに接続しようとすると、クライアント リセット エラーを取得します。
警告
クライアント アプリケーションでクライアント リセット処理を反復処理している間に、同期を繰り返し終了して再度有効にする必要がある場合があります。 同期を終了して再度有効にすると、既存のすべてのクライアントは、クライアントのリセットが完了するまで同期できなくなります。 本番環境でこれを回避するには、開発環境でクライアントのリセット処理をテストします。