Sincronizza le risorse in modo efficiente

Questa guida descrive come implementare la sincronizzazione incrementale dei dati di 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:

  1. Sincronizzazione completa iniziale: eseguita una sola volta all'inizio per sincronizzare completamente lo stato del client con lo stato del server. Il client ottiene un token di sincronizzazione che deve essere persistente.

  2. Sincronizzazione incrementale: eseguita ripetutamente per aggiornare 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 facoltativamente limitare la richiesta di elenco utilizzando i parametri di richiesta.

Nella risposta all'operazione di elenco, la risposta contiene un campo denominato nextSyncToken che rappresenta un token di sincronizzazione. Devi memorizzare il valore di nextSyncToken. Se l'insieme di risultati è troppo grande e la risposta è paginata, il nextSyncToken campo è presente solo nell'ultima pagina.

Sincronizzazione incrementale

La sincronizzazione incrementale ti consente di recuperare tutte le risorse modificate dall'ultima richiesta di sincronizzazione. Per farlo, esegui una richiesta di elenco con il token di sincronizzazione più recente specificato nel campo syncToken. Tieni presente che il risultato contiene sempre le voci eliminate, in modo che i client possano rimuoverle dallo spazio di archiviazione.

Nei casi in cui un numero elevato di risorse è stato modificato dall'ultima richiesta di sincronizzazione incrementale, potresti trovare un pageToken anziché un syncToken nel risultato dell'elenco. In questi casi, esegui la stessa query di elenco utilizzata per recuperare la prima pagina nella sincronizzazione incrementale (con lo stesso syncToken), aggiungi il pageToken e scorri le richieste successive fino a trovare un altro syncToken nell'ultima pagina. Memorizza questo syncToken per la richiesta di sincronizzazione successiva.

Gli esempi seguenti mostrano una sincronizzazione incrementale paginata:

Query originale

GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx

Il risultato contiene quanto segue:

{
  "nextPageToken": "CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA"
}

Recupero della pagina successiva

GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx&pageToken=CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA

Sincronizzazione completa richiesta dal server

A volte il server invalida i token di sincronizzazione a causa della scadenza del token o delle modifiche agli elenchi di controllo dell'accesso correlati. In questi casi, il server risponde a una richiesta incrementale con il codice di stato HTTP 410. Quando ciò si verifica, cancella lo spazio di archiviazione del client ed esegui una nuova sincronizzazione completa.

Codice campione

L'esempio seguente mostra come utilizzare i token di sincronizzazione con la libreria client Java. La prima volta che viene chiamato il metodo run(), esegue una sincronizzazione completa e memorizza il token di sincronizzazione. A ogni esecuzione successiva, carica il token di sincronizzazione salvato ed esegue 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, puoi eseguire la sincronizzazione legacy salvando il valore del campo updated da una richiesta di elenco di eventi e poi utilizzando il campo updatedMin per recuperare gli eventi aggiornati. Questo approccio non è più consigliato perché è più soggetto a errori (ad esempio, non applica le limitazioni delle query) ed è disponibile solo per gli eventi.