Sincronizza le risorse in modo efficiente

Questa guida descrive come implementare la "sincronizzazione incrementale" dei dati del calendario. Utilizzando questo metodo, puoi mantenere sincronizzati i dati per tutte le raccolte di calendari, salvando la larghezza di banda.

Contenuti

Panoramica

La sincronizzazione incrementale prevede due fasi:

  1. La sincronizzazione completa iniziale viene eseguita una volta all'inizio per sincronizzare completamente lo stato del client con lo stato del server. Il client riceverà un token di sincronizzazione che deve essere mantenuto.

  2. La sincronizzazione incrementale viene eseguita ripetutamente e aggiorna il client con tutte le modifiche apportate dalla sincronizzazione precedente. Ogni volta, il client fornisce il token di sincronizzazione precedente ottenuto dal server e archivia il nuovo token di sincronizzazione dalla risposta.

Sincronizzazione completa iniziale

La sincronizzazione completa iniziale è la richiesta originale per tutte le risorse della raccolta che vuoi sincronizzare. Facoltativamente, puoi limitare la richiesta di elenco utilizzando i parametri della richiesta se vuoi sincronizzare solo un sottoinsieme specifico di risorse.

Nella risposta all'operazione di elenco, troverai un campo denominato nextSyncToken che rappresenta un token di sincronizzazione. Devi archiviare il valore di nextSyncToken. Se il set di risultati è troppo grande e la risposta viene suddivisa nella pagina, 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. A tale scopo, devi eseguire una richiesta di elenco 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.

Se un numero elevato di risorse è stato modificato dall'ultima richiesta di sincronizzazione incrementale, potresti trovare pageToken anziché syncToken nei risultati dell'elenco. In questi casi dovrai eseguire esattamente la stessa query dell'elenco che è stata utilizzata per il recupero della prima pagina nella sincronizzazione incrementale (con lo stesso syncToken), aggiungere pageToken e suddividere in pagine tutte le richieste seguenti finché non trovi un altro syncToken nell'ultima pagina. Assicurati di archiviare questo syncToken per la prossima richiesta di sincronizzazione in futuro.

Ecco alcuni esempi di query per una richiesta che richiede la sincronizzazione impaginata incrementale:

Query originale

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

// Result contains the following

"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 i token di sincronizzazione vengono invalidati dal server per vari motivi, tra cui la scadenza del token o le modifiche agli ACL correlati. In questi casi, il server risponderà a una richiesta incrementale con un codice di risposta 410. Questo dovrebbe attivare la cancellazione completa del datastore del client e una nuova sincronizzazione completa.

Codice campione

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 di esecuzione, verrà eseguita una sincronizzazione completa e verrà archiviato il token di sincronizzazione. A ogni esecuzione successiva, il token di sincronizzazione salvato verrà caricato 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 precedente

Per le raccolte di eventi, è comunque possibile eseguire la sincronizzazione in modalità legacy, conservando il valore del campo aggiornato da una richiesta di elenco di eventi e quindi utilizzando il campo modifiedSince per recuperare gli eventi aggiornati. Questo approccio non è più consigliato in quanto è più soggetto a errori rispetto agli aggiornamenti mancanti (ad esempio se non applica limitazioni delle query). Inoltre, è disponibile solo per gli eventi.