Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

동기화 오류 처리 - Node.js SDK

이 페이지의 내용

  • 동기화 오류 처리기
  • 일반 동기화 오류 처리기 추가
  • 보상 쓰기 오류 처리
  • 클라이언트 재설정 오류 처리
  • 클라이언트 재설정 모드
  • 자동 및 수동 클라이언트 재설정
  • 복구를 통한 클라이언트 재설정
  • 동기화되지 않은 변경 사항 복구 모드
  • 동기화되지 않은 변경 사항 복구 또는 삭제 모드
  • 수동 클라이언트 재설정 폴백
  • 동기화되지 않은 변경 사항 삭제 모드
  • 손상적인 스키마 변경 후 동기화되지 않은 변경 사항 삭제
  • 수동 모드
  • 수동 데이터 복구
  • 클라이언트 재설정 처리 테스트

Realm 앱 에서 Atlas Device Sync 를 사용할 때 새로운 유형의 오류인 동기화 오류가 발생할 수 있습니다.

Realm Node.js SDK를 사용하면 동기화 오류를 감지하고 처리할 수 있습니다. 예를 들어 고유한 동기화 오류 핸들러를 작성하여 특정 오류에 응답할 수 있습니다. 클라이언트 앱이 클라이언트 재설정을 처리하는 방법을 정의할 수도 있습니다.

Atlas Device Sync를 사용하는 앱에 대해 오류 핸들러를 설정해야 합니다. 일반 오류 핸들러는 Atlas 백엔드에 대한 동기화 관련 API 호출 실패를 감지하고 이에 응답합니다.

SyncConfiguration의 일부로 오류 콜백 함수를 등록하여 오류 핸들러를 설정합니다.

const handleSyncError = async (session, error) => {
// ... handle the error using session and error information.
console.log(session);
console.log(error);
};
const config = {
schema: [DogSchema],
sync: {
flexible: true,
user: app.currentUser,
onError: handleSyncError,
},
};
// Open realm with config that contains error handler.
const realm = await Realm.open(config);
const handleSyncError = (
session: Realm.App.Sync.Session,
error: Realm.SyncError | Realm.ClientResetError
) => {
// ... handle the error using session and error information.
console.log(session);
console.log(error);
};
const config: Realm.Configuration = {
schema: [DogSchema],
sync: {
flexible: true,
user: app.currentUser!,
onError: handleSyncError,
},
};
// Open realm with config that contains error handler.
const realm = await Realm.open(config);

일반적인 Device Sync 오류 목록과 이를 처리하는 Device Sync 방법은 Atlas App Services 문서에서 동기화 오류 를 참조하세요.

동기화 오류 핸들러가 앱에 적합한 방식으로 보상 쓰기 오류를 구체적으로 해결하기를 원할 수 있습니다. CompensatingWriteError 클래스는 사용자 지정 오류 React 에서 보상 쓰기 오류를 식별하고 대응하는 데 도움이 될 수 있습니다.

const errorCallback = (session, error) => {
// Check if error type matches CompensatingWriteError.
if (error instanceof CompensatingWriteError) {
// Handle the compensating write error as needed.
console.debug({
name: error.name,
code: error.code,
message: error.message,
atlasLogUrl: error.logUrl,
});
const compensatingWrites = error.writes.sort((a, b) =>
a.primaryKey.toString().localeCompare(b.primaryKey.toString())
);
console.debug(compensatingWrites);
}
};
const app = new Realm.App({
id: APP_ID,
});
const credentials = Credentials.anonymous();
await app.logIn(credentials);
const realm = await Realm.open({
schema: [Person, Turtle],
sync: {
flexible: true,
user: app.currentUser,
onError: errorCallback,
},
});
const errorCallback: ErrorCallback = (session, error) => {
// Check if error type matches CompensatingWriteError.
if (error instanceof CompensatingWriteError) {
// Handle the compensating write error as needed.
console.debug({
name: error.name,
code: error.code,
message: error.message,
atlasLogUrl: error.logUrl,
});
const compensatingWrites = error.writes.sort((a, b) =>
(a.primaryKey as BSON.ObjectId)
.toString()
.localeCompare((b.primaryKey as BSON.ObjectId).toString())
);
console.debug(compensatingWrites);
}
};
const app = new Realm.App({
id: APP_ID,
});
const credentials = Credentials.anonymous();
await app.logIn(credentials);
const realm = await Realm.open({
schema: [Person, Turtle],
sync: {
flexible: true,
user: app.currentUser!,
onError: errorCallback,
},
});

클라이언트 재설정 오류 는 클라이언트 영역이 Atlas App Services 백엔드와 데이터를 동기화할 수 없는 시나리오입니다. 이 상태의 클라이언트는 계속 로컬에서 실행하고 데이터를 저장할 수 있지만 클라이언트 재설정을 수행할 때까지 동기화 변경 집합을 보내거나 받을 수 없습니다.

클라이언트 재설정의 원인과 처리 모드에 대해 알아보려면 Device Sync Atlas App Services 문서에서 클라이언트 재설정을 확인하세요.

영역을 동기화 가능 상태로 복원하기 위해 앱에서 사용해야 하는 클라이언트 재설정 모드 를 지정할 수 있습니다.

  • 동기화되지 않은 변경 사항 복구 모드: 이 모드 를 선택하면 클라이언트 는 동기화되지 않은 변경 사항을 복구하려고 시도합니다. 동기화되지 않은 변경 사항을 삭제하지 않으려면 이 모드 를 선택하세요.

  • 동기화되지 않은 변경 사항 복구 또는 삭제 모드: 클라이언트 는 먼저 아직 동기화되지 않은 변경 사항 복구를 시도합니다. 클라이언트 가 동기화되지 않은 데이터를 복구할 수 없는 경우 동기화되지 않은 변경 사항을 삭제하지만 계속 자동으로 클라이언트 재설정 을 수행합니다. 동기화되지 않은 변경 사항을 삭제하도록 자동 클라이언트 복구를 활성화 하려면 이 모드 를 선택합니다.

  • 동기화되지 않은 변경 사항 삭제 모드: 마지막 동기화 이후 변경된 내용을 삭제하여 영역 을 동기화 가능한 상태 로 복원합니다.

  • 수동 복구 모드: Realm의 새 복사본을 다운로드하고 동기화할 수 없는 Realm을 백업으로 이동합니다. Realm의 백업 복사본에서 동기화 가능한 새 복사본으로 동기화되지 않은 데이터를 마이그레이션합니다.

Realm SDK는 대부분의 클라이언트 재설정 오류를 자동으로 처리하는 클라이언트 재설정 모드를 제공합니다.

자동 클라이언트 재설정 모드는 영역을 닫거나 알림을 누락하지 않고 로컬 Realm 파일을 동기화 가능한 상태로 복원합니다. The following client reset modes support automatic client resets:

  • 동기화되지 않은 변경 사항 복구 모드

  • 동기화되지 않은 변경 사항 복구 또는 삭제 모드

  • 동기화되지 않은 변경 사항 삭제 모드

이러한 모드의 차이점은 아직 백엔드에 동기화되지 않은 기기의 변경 사항을 처리하는 방법에 따라 달라집니다. 수동 복구 모드만 자동 클라이언트 재설정을 수행하지 않습니다.

동기화되지 않은 변경 사항 복구 모드를 선택하여 대부분의 클라이언트 재설정 시나리오를 자동으로 처리합니다. 이렇게 하면 클라이언트 재설정이 발생할 때 동기화되지 않은 변경 사항을 복구하려고 시도합니다.

앱에 자동으로 처리할 수 없는 특정 클라이언트 재설정 로직이 필요한 경우 자동 클라이언트 재설정 모드 에 수동 클라이언트 재설정 처리기를 추가 해야 할 수 있습니다.

버전 10.23.0의 새로운 기능

클라이언트 복구는 Realm Mobile Sync를 구성할 때 기본적으로 활성화되는 기능입니다. 클라이언트 복구가 활성화되면 Realm은 대부분의 경우 클라이언트 재설정 프로세스를 managed합니다. 클라이언트는 스키마 변경 사항이 없는 경우 동기화되지 않은 변경 사항을 복구하거나 호환성이 손상되지 않는 스키마 변경 사항을 복구할 수 있습니다.

클라이언트 복구를 사용하려면 다음 클라이언트 재설정 모드 중 하나로 영역을 구성하세요.

  • 동기화되지 않은 변경 사항 복구 모드

  • 동기화되지 않은 변경 사항 복구 또는 삭제

클라이언트 복구가 활성화된 경우 이러한 규칙은 백엔드와 클라이언트가 모두 동일한 객체를 변경할 때 충돌을 해결하는 방법을 포함하여 객체가 통합되는 방식을 결정합니다.

  • 로컬에서 생성되었지만 클라이언트 재설정 전에 동기화되지 않은 객체는 동기화됩니다.

  • 객체가 서버에서 삭제되었지만 복구 클라이언트에서 수정된 경우 삭제가 우선적으로 적용되고 클라이언트는 업데이트를 삭제합니다.

  • 객체가 복구 중인 클라이언트에서는 삭제되고 서버에서는 삭제되지 않는 경우 클라이언트는 서버의 삭제 명령을 적용합니다.

  • 동일한 필드에 대한 업데이트가 충돌하는 경우 클라이언트 업데이트가 적용됩니다.

클라이언트 복구 구성에 대한 자세한 내용은 Atlas App Services 문서의 클라이언트 복구 를 참조하세요.

앱에서 손상적인 스키마 변경이 발생하면 클라이언트 복구가 성공할 수 없습니다. 단절적 변경은 서버 측 스키마에서 처리할 추가 조치가 필요한 변경 사항입니다. 이 시나리오에서 클라이언트 재설정은 수동 오류 클라이언트 재설정 대체로 대체됩니다.

단절적 스키마 변경과 단절적이지 않은 변경에 대한 자세한 내용은 Atlas App Services 문서에서 단절과 단절적이지 않은 변경 비교 빠른 참조 를 참조하세요.

동기화되지 않은 변경 사항 복구 모드를 선택하면 클라이언트는 클라이언트 복구를 사용하여 동기화되지 않은 변경 사항을 복구하려고 시도합니다. 동기화되지 않은 변경 사항을 삭제하고 싶지 않을 때 이 모드를 선택하세요.

동기화되지 않은 변경 사항 복구 모드 로 클라이언트 재설정을 처리하다 하려면 clientReset SyncConfiguration 의 필드 에 ClientResetConfig 를 전달합니다. ClientResetConfiguration 에 다음 속성을 포함합니다.

  • mode: "recoverUnsyncedChanges" 로 설정합니다.

  • onBefore: 선택 사항입니다. SDK가 백엔드에서 클라이언트 재설정 오류를 수신하는 경우, SDK가 이 모드를 실행하기 전에 호출되는 콜백 함수입니다. 영역의 복사본을 제공합니다.

  • onAfter: 선택 사항입니다. SDK가 이 모드를 성공적으로 실행한 후 호출되는 콜백 함수입니다. 클라이언트 재설정 전후의 영역 인스턴스를 제공합니다.

  • onFallback: 선택 사항입니다. 자동 복구가 실패한 경우에만 SDK가 호출하는 콜백 함수입니다. 자세한 내용은 수동 클라이언트 재설정 폴백 섹션을 참조하세요.

다음 예에서는 동기화되지 않은 변경 사항 복구 모드를 구현합니다.

const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "recoverUnsyncedChanges",
onBefore: (realm) => {
// This block could be used for custom recovery, reporting, debugging etc.
},
onAfter: (beforeRealm, afterRealm) => {
// This block could be used for custom recovery, reporting, debugging etc.
},
onFallback: (session, path) => {
// See below "Manual Client Reset Fallback" section for example
},
},
},
};

동기화되지 않은 변경 사항 복구 또는 삭제 모드에서 클라이언트는 먼저 아직 동기화되지 않은 변경 사항을 복구하려고 시도합니다. 클라이언트가 동기화되지 않은 데이터를 복구할 수 없는 경우 동기화되지 않은 변경 사항을 삭제하지만 계속 자동으로 클라이언트 재설정을 수행합니다. 동기화되지 않은 변경 사항을 삭제하도록 자동 클라이언트 복구를 활성화하려는 경우 이 모드를 선택합니다.

애플리케이션에서 아직 백엔드에 동기화되지 않은 로컬 데이터를 잃을 수 없는 경우 복구 또는 동기화되지 않은 변경 사항 삭제 모드를 사용하지 마세요.

동기화되지 않은 변경 사항 복구 또는 삭제 모드 로 클라이언트 재설정을 처리하다 하려면 clientReset SyncConfiguration 의 필드 에 ClientResetConfig 를 전달합니다. ClientResetConfiguration 에 다음 속성을 포함합니다.

  • mode: "recoverOrDiscardUnsyncedChanges" 로 설정합니다.

  • onBefore: 선택 사항입니다. SDK가 백엔드에서 클라이언트 재설정 오류를 수신하는 경우, SDK가 이 모드를 실행하기 전에 호출되는 콜백 함수입니다. 영역의 복사본을 제공합니다.

  • onAfter: 선택 사항입니다. SDK가 이 모드를 성공적으로 실행한 후 호출되는 콜백 함수입니다. 클라이언트 재설정 전후의 영역 인스턴스를 제공합니다.

  • onFallback: 선택 사항입니다. 자동 복구와 변경 사항 삭제가 모두 실패하는 경우에만 SDK가 호출하는 콜백 함수입니다. 자세한 내용은 수동 클라이언트 재설정 폴백 섹션을 참조하세요.

다음 예에서는 동기화되지 않은 변경 사항 복구 모드를 구현합니다.

const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "recoverOrDiscardUnsyncedChanges",
onBefore: (realm) => {
// This block could be used for custom recovery, reporting, debugging etc.
},
onAfter: (beforeRealm, afterRealm) => {
// This block could be used for custom recovery, reporting, debugging etc.
},
onFallback: (session, path) => {
// See below "Manual Client Reset Fallback" section for example
},
},
},
};

복구를 포함한 클라이언트 재설정을 자동으로 완료할 수 없는 경우(예: 손상적인 스키마 변경이 있는 경우) 클라이언트 재설정 프로세스는 수동 오류 처리기에게로 넘어갑니다. 이는 클라이언트 재설정이 복구 모드로, 동기화되지 않은 변경 사항을 복구하고, 동기화되지 않은 변경 사항을 복구하거나 삭제할 때 발생할 수 있습니다.

SyncConfiguration.onFallback() 콜백에서 수동 클라이언트 재설정 구현을 제공해야 합니다. onFallback() 은 두 개의 인수를 사용합니다.

  • session: Device Sync 세션의 상태 를 나타내는 세션 객체 입니다.

  • path: 현재 Realm 파일의 경로가 포함된 문자열입니다.

다음 예에서는 동기화되지 않은 모든 변경 사항을 삭제하여 이 오류 사례를 수동으로 처리하는 방법을 보여 줍니다.

// Must define `realm` at higher scope than `config` so it's accessible
// from the `onFallback` callback
let realm;
const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "recoverOrDiscardUnsyncedChanges", // or "recoverUnsyncedChanges"
// can also include `onBefore` and `onAfter` callbacks
onFallback: (_session, path) => {
try {
// 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.
const didUserConfirmReset = showUserAConfirmationDialog();
if (didUserConfirmReset) {
// Close and delete old realm from device
realm.close();
Realm.deleteFile(path);
// Perform client reset
Realm.App.Sync.initiateClientReset(app, path);
// Navigate the user back to the main page or reopen the
// the Realm and reinitialize the current page
}
} catch (err) {
// Reset failed. Notify user that they'll need to
// update the app
}
},
},
},
};
realm = await Realm.open(config);

버전 10.11.0의 새로운 기능.

버전 10.23.0에서 변경됨: 모드 이름이 "discardLocal"에서 "discardUnsyncedChanges"로 변경되었습니다. 현재는 둘 다 작동하지만, 향후 버전에서는 'discardLocal'이 제거될 예정입니다. 'clientResetBefore' 및 'clientResetAfter' 콜백의 이름이 각각 'onBefore' 및 'onAfter'로 변경되었습니다.

동기화 되지 않은 변경 사항 삭제 모드 는 마지막 동기화 에 성공적인 이후 이루어진 모든 동기화되지 않은 로컬 변경 사항을 영구적으로 삭제합니다. 앱 에 자동 클라이언트 복구 와 일관적인 하지 않는 클라이언트 복구 로직이 필요하거나 동기화되지 않은 데이터를 복구하지 않으려는 경우 이 모드 를 사용할 수 있습니다.

애플리케이션에서 아직 백엔드에 동기화되지 않은 로컬 데이터를 잃을 수 없는 경우 동기화되지 않은 변경 사항 삭제 모드를 사용하지 마세요.

동기화되지 않은 변경 사항 삭제 모드 로 클라이언트 재설정을 처리하다 하려면 clientReset SyncConfiguration 의 필드 에 ClientResetConfig 를 전달합니다. ClientResetConfiguration 에 다음 속성을 포함합니다.

  • mode: "discardUnsyncedChanges" 로 설정합니다.

  • onBefore: 선택 사항입니다. SDK가 백엔드에서 클라이언트 재설정 오류를 수신하는 경우, SDK가 이 모드를 실행하기 전에 호출되는 콜백 함수입니다. 영역의 복사본을 제공합니다.

  • onAfter: 선택 사항입니다. SDK가 이 모드를 성공적으로 실행한 후 호출되는 콜백 함수입니다. 클라이언트 재설정 전후의 영역 인스턴스를 제공합니다.

다음 예제에서는 동기화되지 않은 변경 사항 삭제 모드를 구현합니다.

const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "discardUnsyncedChanges",
onBefore: (realm) => {
console.log("Beginning client reset for ", realm.path);
},
onAfter: (beforeRealm, afterRealm) => {
console.log("Finished client reset for", beforeRealm.path);
console.log("New realm path", afterRealm.path);
},
},
},
};

애플리케이션에서 손상적인 스키마 변경이 발생하는 경우 동기화되지 않은 변경 사항 삭제 모드는 결과적인 클라이언트 재설정을 자동으로 처리할 수 없습니다. 대신 SyncConfiguration error() 콜백에서 수동 클라이언트 재설정 구현을 제공해야 합니다. 다음 예에서는 동기화되지 않은 모든 변경 사항을 삭제하여 이 오류 사례를 수동으로 처리하는 방법을 보여 줍니다.

// Once you have opened your Realm, you will have to keep a reference to it.
// In the error handler, this reference is called `realm`
async function handleSyncError(session, syncError) {
if (syncError.name == "ClientReset") {
console.log(syncError);
try {
console.log("error type is ClientReset....");
const path = realm.path; // realm.path will not be accessible after realm.close()
realm.close();
Realm.App.Sync.initiateClientReset(app, path);
// Download Realm from the server.
// Ensure that the backend state is fully downloaded before proceeding,
// which is the default behavior.
realm = await Realm.open(config);
realm.close();
} catch (err) {
console.error(err);
}
} else {
// ...handle other error types
}
}
const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "discardUnsyncedChanges",
onBefore: (realm) => {
// NOT used with destructive schema changes
console.log("Beginning client reset for ", realm.path);
},
onAfter: (beforeRealm, afterRealm) => {
// Destructive schema changes do not hit this function.
// Instead, they go through the error handler.
console.log("Finished client reset for", beforeRealm.path);
console.log("New realm path", afterRealm.path);
},
},
onError: handleSyncError, // invoked with destructive schema changes
},
};

참고

복구 후 삭제

동기화되지 않은 변경 사항을 복구하려고 시도하지만 복구할 수 없는 변경 사항을 삭제하려면 동기화되지 않은 변경 사항 복구 또는 삭제 모드 섹션을 참조하세요.

버전 10.23.0에서 변경: onManual 콜백 추가

수동 모드에서는 클라이언트 재설정 처리기를 직접 정의할 수 있습니다. 자동 복구 로직이 앱에서 작동하지 않고 동기화되지 않은 로컬 데이터를 삭제할 수 없는 경우 수동 클라이언트 재설정 핸들러를 사용할 수 있습니다.

수동 모드 로 클라이언트 재설정을 처리하다 하려면 clientReset SyncConfiguration 의 필드 에 ClientResetConfig 를 전달합니다. ClientResetConfiguration 에 다음 속성을 포함합니다.

  • mode: "manual" 로 설정합니다.

  • onManual: 선택 사항입니다. 클라이언트 재설정이 발생할 때 호출되는 콜백 함수입니다. 동기화 세션 및 현재 영역의 경로에 대한 정보를 제공합니다. onManual 오류 핸들러를 설정하지 않으면 클라이언트 재설정 오류는 일반 동기화 오류 핸들러로 돌아갑니다.

const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "manual",
onManual: (session, path) => {
// handle manual client reset here
},
},
},
};

수동 클라이언트 재설정에서 데이터를 복구하려면 상당한 양의 코드, 스키마 양보 및 사용자 지정 충돌 해결 로직이 필요합니다. 사용자 지정 클라이언트 재설정 로직을 구현해야 하는 경우 수동 클라이언트 재설정 데이터 복구 고급 가이드를 참조하세요.

Device Sync를 종료했다가 다시 활성화하여 애플리케이션의 클라이언트 재설정 처리를 수동으로 테스트할 수 있습니다.

동기화를 종료했다가 다시 허용하면 이전에 동기화로 연결한 클라이언트는 클라이언트 재설정을 수행할 때까지 연결할 수 없습니다. 동기화를 종료하면 클라이언트의 동기화를 허용하는 메타데이터가 서버에서 삭제됩니다. 클라이언트는 서버에서 영역의 새 복사본을 다운로드해야 합니다. 서버는 이러한 클라이언트에 클라이언트 재설정 오류를 보냅니다. 따라서 동기화를 종료하면 trigger 클라이언트 재설정 조건이 됩니다.

클라이언트 재설정 처리를 테스트하려면 다음을 수행합니다.

  1. 클라이언트 애플리케이션에서 데이터를 쓰고 동기화될 때까지 기다립니다.

  2. Realm Mobile Sync를 종료했다가 다시 활성화합니다.

  3. 클라이언트 앱을 다시 실행합니다. 앱이 서버에 연결하려고 할 때 클라이언트 재설정 오류가 발생해야 합니다.

경고

클라이언트 애플리케이션에서 클라이언트 재설정 처리를 반복하는 동안 동기화를 종료했다가 다시 활성화해야 할 수 있습니다. 동기화를 종료했다가 다시 활성화하면 클라이언트 재설정을 완료할 때까지 기존의 모든 클라이언트를 동기화할 수 없습니다. 프로덕션 환경에서 이를 방지하려면 개발 환경에서 클라이언트 재설정 처리를 테스트하세요.

돌아가기

동기화 세션 관리