Gerenciar erros de sincronização - C++ SDK
Nesta página
- Gerenciar erros de sincronização
- Reinício do cliente
- reinício do cliente automático versus manual
- Especificar um modo de reinício do cliente
- Lidar com alterações no esquema
- Recuperar alterações não sincronizadas
- Descartar alterações não sincronizadas
- Modo de reinício do cliente
- Tratamento de reinício do cliente de teste
Gerenciar erros de sincronização
Ao desenvolver uma aplicação que usa o Realm Mobile Sync, você deve definir um manipulador de erros. Esse manipulador de erros detecta e pode responder a quaisquer chamadas de API relacionadas à sincronização com falha.
Defina um manipulador de erro no sync_config. Quando ocorre um erro, o C++ SDK++ chama o manipulador de erro com o objeto sync_error e a sync_session onde ocorreu o erro.
auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); auto user = app.login(realm::App::credentials::anonymous()).get(); auto dbConfig = user.flexible_sync_configuration(); // Setting an error handler on the sync_config gives you access to // sync_session and sync_error dbConfig.sync_config().set_error_handler( [](const realm::sync_session &session, const realm::internal::bridge::sync_error &error) { std::cerr << "A sync error occurred. Message: " << error.message() << std::endl; }); auto syncRealm = realm::db(dbConfig);
Dica
Para obter uma lista de erros comuns do Device Sync e como gerenciá-los, consulte Erros de sincronização na documentação do Atlas App Services Device Sync .
Reinício do cliente
Ao usar o Device Sync, um reinício do cliente é uma tarefa de recuperação de erros que seu aplicativo cliente deve executar quando o servidor não puder mais sincronizar com o banco de banco de dados do dispositivo. Nesse caso, o dispositivo deve redefinir seu banco de dados de dados para um estado que corresponda ao servidor para restaurar a capacidade de sincronização.
Quando isso ocorre, o banco de dados não sincronizável no dispositivo pode conter dados que ainda não foram sincronizados com o servidor. O SDK pode tentar recuperar ou descartar esses dados durante o processo de reinício do cliente.
Para obter mais informações sobre o que pode causar a ocorrência de um reinício do cliente, Go Redefinições do cliente na documentação do Atlas App Services .
reinício do cliente automático versus manual
O SDK fornece modos de reinício do cliente que gerenciam automaticamente a maioria dos erros de reinício do cliente . Os modos automáticos de reinício do cliente restauram o arquivo do banco de dados de dados do seu dispositivo para um estado sincronizável sem fechar o banco de dados de dados ou perder notificações.
Todos os modos de reinício do cliente, exceto manual()
, executam um reinício do cliente automático. As diferenças entre os modos são baseadas em como eles lidam com alterações no dispositivo que ainda não foram sincronizadas com o backend.
Escolha recover_unsynced_changes()
para lidar com a maioria dos cenários de reinício do cliente automaticamente. Isso tenta recuperar alterações não sincronizadas quando ocorre um reinício do cliente.
Em alguns casos, você pode desejar ou precisar definir um manipulador manual de redefinição do cliente. Talvez você queira fazer isso se o seu aplicativo exigir lógica de redefinição de cliente específica que não possa ser tratada automaticamente.
Especificar um modo de reinício do cliente
O C++ SDK fornece a opção de especificar um manipulador de redefinição do cliente na configuração do banco de dados. Este manipulador de redefinição de cliente pode receber um client_reset_mode_base. Esta estrutura permite especificar:
Um bloco a ser executado antes do reinício do cliente
Um bloco a ser executado após o reinício do cliente
O modo a ser usado ao lidar com a redefinição do cliente
auto user = app.login(realm::App::credentials::anonymous()).get(); auto syncConfig = user.flexible_sync_configuration(); // Set the client reset handler with your preferred client reset mode. syncConfig.set_client_reset_handler( realm::client_reset::recover_unsynced_changes(beforeReset, afterReset)); auto syncedRealm = realm::db(syncConfig);
Você pode usar um dos modos de redefinição de cliente disponíveis para especificar como o SDK deve tentar resolver quaisquer dados não sincronizados no dispositivo durante uma redefinição de cliente:
recover_unsynced_changes()
recover_or_discard_unsynced_changes()
discard_unsynced_changes()
manual()
Você pode especificar um bloco antes e depois para ser executado durante o processo automático de reinício do cliente. Você pode usar isso para executar a lógica de recuperação que é importante para seu aplicativo.
/* You can define blocks to call before and after the client reset occur if you need to execute specific logic, such as reporting or debugging. */ auto beforeReset = [&](realm::db before) { /* A block called after a client reset error is detected, but before the client recovery process is executed. You could use this block for any custom logic, reporting, debugging etc. You have access to the database before the client reset occurs in this block. */ }; auto afterReset = [&](realm::db device, realm::db server) { /* A block called after the client recovery process has executed. This block could be used for custom recovery, reporting, debugging etc. You have access to the database that is currently on the device - the one that can no longer sync - and the new database that has been restored from the server. */ };
Se seu aplicativo tiver necessidades específicas de recuperação do cliente, você poderá especificar o modo de reinício do cliente manual()
e definir um manipulador manual de reinício do cliente. Você pode fazer isso se tiver uma lógica personalizada específica que seu aplicativo deve executar durante a redefinição de um cliente ou se as regras de recuperação do cliente não funcionarem para seu aplicativo.
Lidar com alterações no esquema
A recuperação de cliente é um recurso que é habilitado por padrão quando você configura o Device Sync. Quando a Recuperação de Cliente está ativada, o SDK pode gerenciar automaticamente o processo de redefinição do cliente na maioria dos casos. Quando você faz alterações no esquema:
O cliente pode recuperar alterações não sincronizadas quando não houver alterações no esquema ou alterações no esquema não significativas.
Quando você faz alterações significativas no esquema, os modos automáticos de reinício do cliente voltam para um manipulador manual de erros. Você pode definir um manipulador de erro de redefinição manual do cliente para esse caso. A recuperação automática do cliente não pode ocorrer quando seu aplicativo faz alterações significativas no esquema.
Para obter informações sobre alterações de esquema significativas e não significativas, consulte Referência rápida de alterações significativas versus não significativas.
Recuperar alterações não sincronizadas
Durante uma redefinição do cliente, os aplicativos do cliente podem tentar recuperar dados no banco de dados sincronizado no dispositivo que ainda não foram sincronizados com o backend. Para recuperar alterações não sincronizadas, a Recuperação de cliente deve estar ativada em seu App Services App, que é por padrão.
Se quiser que seu aplicativo recupere alterações que ainda não foram sincronizadas, use um destes modos de recuperação de cliente:
recover_unsynced_changes()
: o cliente tenta recuperar alterações não sincronizadas. Escolha este modo se não quiser descartar alterações não sincronizadas.recover_or_discard_unsynced_changes()
: o cliente primeiro tenta recuperar as alterações que ainda não foram sincronizadas. Se o cliente não conseguir recuperar dados não sincronizados, ele falhará no descarte das alterações não sincronizadas, mas continuará executando automaticamente o reinício do cliente. Escolha este modo quando quiser ativar a recuperação automática do cliente para voltar a descartar alterações não sincronizadas.
auto user = app.login(realm::App::credentials::anonymous()).get(); auto syncConfig = user.flexible_sync_configuration(); // Set the client reset handler with your preferred client reset mode. syncConfig.set_client_reset_handler( realm::client_reset::recover_unsynced_changes(beforeReset, afterReset)); auto syncedRealm = realm::db(syncConfig);
Pode haver momentos em que a operação de reinício do cliente não pode ser concluída no modo recover_unsynced_changes()
, como quando há alterações no esquema de quebra ou a Recuperação do Cliente está desativada na configuração do Device Sync . Para lidar com esse caso, seu aplicativo pode lidar com um erro de reinício do cliente no manipulador de erros de sincronização. Para obter mais informações, consulte a seção modo de reinício do cliente nesta página.
Regras de recuperação do cliente
Quando a Recuperação de Cliente está habilitada, essas regras determinam como os objetos são integrados, incluindo como os conflitos são resolvidos quando o backend e o cliente fazem alterações no mesmo objeto:
Objetos criados localmente que não foram sincronizados antes da redefinição do cliente são sincronizados.
Se um objeto for excluído no servidor, mas for modificado no cliente de recuperação, a exclusão terá precedência e o cliente descartará a atualização.
Se um objeto for excluído no cliente em recuperação, mas não no servidor, o cliente aplicará a instrução de exclusão do servidor.
No caso de atualizações conflitantes no mesmo campo, a atualização do cliente é aplicada.
Descartar alterações não sincronizadas
O modo de reinício do cliente discard_unsynced_changes()
exclui permanentemente todas as alterações não sincronizadas no dispositivo desde a última sincronização bem-sucedida. Você pode usar esse modo quando seu aplicativo exigir uma lógica de recuperação de cliente que não seja consistente com as regras de recuperação de cliente do Device Sync ou quando você não quiser recuperar dados não sincronizados.
Não use o modo de descarte de alterações não sincronizadas se o aplicativo não puder perder dados do dispositivo que ainda não foram sincronizados com o backend.
Para executar um reinício do cliente automático que descarta alterações não sincronizadas, utilize o modo de reinício do cliente do discard_unsynced_changes()
.
auto user = app.login(realm::App::credentials::anonymous()).get(); auto syncConfig = user.flexible_sync_configuration(); // Set the client reset handler with your preferred client reset mode. syncConfig.set_client_reset_handler( realm::client_reset::discard_unsynced_changes(beforeReset, afterReset)); auto syncedRealm = realm::db(syncConfig);
Observação
Descartar com recuperação
Se você quiser tentar recuperar as alterações não sincronizadas, mas descartar todas as alterações que não podem ser recuperadas, consulte a documentação do recover_or_discard_unsynced_changes()
na seção Recuperar alterações não sincronizadas nesta página.
Pode haver momentos em que a operação de reinício do cliente não pode ser concluída no modo discard_unsynced_changes()
, como quando há alterações significativas no esquema. Para lidar com esse caso, seu aplicativo pode lidar com um erro de redefinição do cliente no manipulador de erros de sincronização. Para obter mais informações, consulte a seção Modo de reinício do cliente manual nesta página.
Modo de reinício do cliente
Ao usar o modo de reinício do cliente manual()
, você deve implementar um manipulador personalizado de reinício do cliente no manipulador de erros de sincronização. Recomendamos usar os modos de recuperação automática de cliente quando possível e escolher o modo manual()
somente se a lógica de recuperação automática não for adequada para seu aplicativo.
auto user = app.login(realm::App::credentials::anonymous()).get(); auto syncConfig = user.flexible_sync_configuration(); // Set the client reset handler to manual client reset mode. syncConfig.set_client_reset_handler(realm::client_reset::manual()); // Define a Sync error handler for handling the client reset. syncConfig.sync_config().set_error_handler( [&](realm::sync_session session, realm::sync_error error) { if (error.is_client_reset_requested()) { /* You might use this for reporting or to instruct the user to delete and re-install the app. */ }; }); auto syncedRealm = realm::db(syncConfig);
Se a operação de reinício do cliente não puder ser concluída automaticamente, como quando há alterações de esquema de quebra, o processo de reinício do cliente passará para o manipulador de erros manual. Isso pode ocorrer em qualquer um destes modos automáticos de reinício do cliente:
recover_unsynced_changes()
recover_or_discard_unsynced_changes()
discard_unsynced_changes()
Recomendamos tratar o manipulador manual como uma ferramenta para situações de recuperação de erros fatais em que você aconselha os usuários a atualizar o aplicativo ou executar alguma outra ação.
Tratamento de reinício do cliente de teste
Você pode testar manualmente o tratamento de redefinição do cliente do seu aplicativo encerrando e reativando o Device Sync.
Quando você encerra e reativa a sincronização, os clientes que se conectaram anteriormente à sincronização não conseguem se conectar até depois de fazerem um reinício do cliente. O encerramento da sincronização exclui os metadados do servidor que permitem ao cliente sincronizar. O cliente deve baixar uma nova cópia do Realm do servidor. O servidor envia um erro de reinício do cliente para esses clientes. Então, ao encerrar a sincronização, você trigger a condição de reinício do cliente.
Para testar o tratamento de reinício do cliente:
Escreva dados de um aplicativo cliente e aguarde a sincronização.
Encerre e reative o Realm Mobile Sync.
Run the client app again. O aplicativo deve receber um erro de reinício do cliente ao tentar se conectar ao servidor.
Aviso
Enquanto você itera sobre o tratamento de redefinição do cliente em seu aplicativo cliente, talvez seja necessário encerrar e reativar a sincronização repetidamente. Encerrar e reativar a sincronização impede que todos os clientes existentes sincronizem até depois de concluir a redefinição do cliente. Para evitar isso na produção, teste o tratamento de redefinição do cliente em um ambiente de desenvolvimento.