Questa guida descrive come implementare la "sincronizzazione incrementale" dei dati del calendario. Utilizzando questo metodo, puoi mantenere sincronizzati i dati di tutte le raccolte di calendari risparmiando larghezza di banda.
Sommario
Panoramica
La sincronizzazione incrementale è costituita da due fasi:
La sincronizzazione completa iniziale viene eseguita una sola volta all'inizio per sincronizzare completamente lo stato del client con quello del server. Il client otterrà un token di sincronizzazione che deve essere reso persistente.
La sincronizzazione incrementale viene eseguita ripetutamente e aggiorna il client con tutte le modifiche apportate dall'ultima sincronizzazione. Ogni volta, il client fornisce il token di sincronizzazione precedente ottenuto dal server e memorizza il nuovo token di sincronizzazione dalla risposta.
Sincronizzazione completa iniziale
La sincronizzazione completa iniziale è la richiesta originale di tutte le risorse della raccolta che vuoi sincronizzare. Se vuoi sincronizzare solo un sottoinsieme specifico di risorse, puoi limitare facoltativamente la richiesta di elenco utilizzando i parametri di richiesta.
Nella risposta all'operazione di elenco, troverai un campo chiamato
nextSyncToken
che rappresenta un token di sincronizzazione. Dovrai memorizzare il valore di
nextSyncToken
. Se il set di risultati è troppo grande e la risposta viene
impaginata, il campo nextSyncToken
è presente solo nell'ultima pagina.
Sincronizzazione incrementale
La sincronizzazione incrementale consente di recuperare tutte le risorse che sono state
modificate dall'ultima richiesta di sincronizzazione. Per farlo, devi eseguire una richiesta
list con il token di sincronizzazione più recente specificato nel campo syncToken
.
Tieni presente che il risultato conterrà sempre le voci eliminate, in modo che i
client abbiano la possibilità di rimuoverle dallo spazio di archiviazione.
Nei casi in cui un numero elevato di risorse è cambiato dall'ultima
richiesta di sincronizzazione incrementale, potresti trovare un pageToken
anziché un syncToken
nel risultato dell'elenco. In questi casi, devi eseguire la stessa query di elenco utilizzata per il recupero della prima pagina nella sincronizzazione incrementale (con lo stesso syncToken
), aggiungere pageToken
e scorrere tutte le richieste successive fino a quando non trovi un altro syncToken
nell'ultima pagina. Assicurati di memorizzare questo syncToken
per la prossima richiesta di sincronizzazione in futuro.
Ecco alcune query di esempio per un caso che richiede la sincronizzazione incrementale paginata:
Query originale
GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx
// Result contains the following
"nextPageToken":"CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA",
Recupero della pagina successiva in corso…
GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx&pageToken=CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA
Sincronizzazione completa richiesta dal server
A volte i token di sincronizzazione vengono invalidati dal server per vari motivi, tra cui la scadenza del token o modifiche agli ACL correlati.
In questi casi, il server risponderà a una richiesta incrementale con un codice di risposta 410
. In questo modo verrà attivata una cancellazione completa dello store del cliente
e una nuova sincronizzazione completa.
Codice di esempio
Lo snippet di codice di esempio riportato di seguito mostra come utilizzare i token di sincronizzazione con la libreria client Java. La prima volta che viene chiamato il metodo run, viene eseguita una sincronizzazione completa e viene memorizzato il token di sincronizzazione. A ogni esecuzione successiva, caricherà il token di sincronizzazione salvato ed eseguirà una sincronizzazione incrementale.
private static void run() throws IOException { // Construct the {@link Calendar.Events.List} request, but don't execute it yet. Calendar.Events.List request = client.events().list("primary"); // Load the sync token stored from the last execution, if any. String syncToken = syncSettingsDataStore.get(SYNC_TOKEN_KEY); if (syncToken == null) { System.out.println("Performing full sync."); // Set the filters you want to use during the full sync. Sync tokens aren't compatible with // most filters, but you may want to limit your full sync to only a certain date range. // In this example we are only syncing events up to a year old. Date oneYearAgo = Utils.getRelativeDate(java.util.Calendar.YEAR, -1); request.setTimeMin(new DateTime(oneYearAgo, TimeZone.getTimeZone("UTC"))); } else { System.out.println("Performing incremental sync."); request.setSyncToken(syncToken); } // Retrieve the events, one page at a time. String pageToken = null; Events events = null; do { request.setPageToken(pageToken); try { events = request.execute(); } catch (GoogleJsonResponseException e) { if (e.getStatusCode() == 410) { // A 410 status code, "Gone", indicates that the sync token is invalid. System.out.println("Invalid sync token, clearing event store and re-syncing."); syncSettingsDataStore.delete(SYNC_TOKEN_KEY); eventDataStore.clear(); run(); } else { throw e; } } List<Event> items = events.getItems(); if (items.size() == 0) { System.out.println("No new events to sync."); } else { for (Event event : items) { syncEvent(event); } } pageToken = events.getNextPageToken(); } while (pageToken != null); // Store the sync token from the last request to be used during the next execution. syncSettingsDataStore.set(SYNC_TOKEN_KEY, events.getNextSyncToken()); System.out.println("Sync complete."); }
Sincronizzazione legacy
Per le raccolte di eventi, è ancora possibile eseguire la sincronizzazione nel
modo precedente conservando il valore del campo aggiornato da un elenco di eventi
e poi utilizzando il campo modifiedSince
per recuperare gli eventi aggiornati.
Questo approccio non è più consigliato perché è più soggetto a errori rispetto
agli aggiornamenti mancati (ad esempio, se non applica restrizioni alle query).
Inoltre, è disponibile solo per gli eventi.