Efektywne synchronizowanie zasobów

W tym przewodniku opisano, jak wdrożyć „synchronizację przyrostową” danych kalendarza. Dzięki tej metodzie możesz synchronizować dane wszystkich kolekcji kalendarza, oszczędzając przy tym przepustowość.

Spis treści

Przegląd

Synchronizacja przyrostowa składa się z 2 etapów:

  1. Początkowa pełna synchronizacja jest wykonywana raz na samym początku, aby w pełni zsynchronizować stan klienta ze stanem serwera. Klient uzyska token synchronizacji, który musi być trwały.

  2. Synchronizacja przyrostowa jest wykonywana wielokrotnie i aktualizuje klienta o wszystkie zmiany, które nastąpiły od czasu poprzedniej synchronizacji. Za każdym razem klient udostępnia poprzedni token synchronizacji uzyskany z serwera i zapisuje nowy token synchronizacji z odpowiedzi.

Pierwsza pełna synchronizacja

Pierwsza pełna synchronizacja to pierwotne żądanie dotyczące wszystkich zasobów kolekcji, którą chcesz synchronizować. Jeśli chcesz synchronizować tylko określony podzbiór zasobów, możesz opcjonalnie ograniczyć żądanie wyświetlenia listy za pomocą parametrów żądania.

W odpowiedzi na operację wyświetlania listy znajdziesz pole o nazwie nextSyncToken reprezentujące token synchronizacji. Musisz zapisać wartość właściwości nextSyncToken. Jeśli zbiór wyników jest za duży, a odpowiedź jest dzielona na strony, pole nextSyncToken znajduje się tylko na ostatniej stronie.

Synchronizacja przyrostowa

Synchronizacja przyrostowa umożliwia pobranie wszystkich zasobów, które zostały zmodyfikowane od czasu ostatniego żądania synchronizacji. Aby to zrobić, wyślij żądanie wyświetlenia listy, używając najnowszego tokena synchronizacji określonego w polu syncToken. Pamiętaj, że wynik zawsze będzie zawierał usunięte wpisy, aby klienci mogli usunąć je z pamięci.

Jeśli od czasu ostatniego żądania synchronizacji przyrostowej zmieniła się duża liczba zasobów, w wyniku listy możesz znaleźć pageToken zamiast syncToken. W takich przypadkach musisz wykonać dokładnie to samo zapytanie o listę, które było używane w przypadku pobierania pierwszej strony w synchronizacji przyrostowej (z takim samym ustawieniem syncToken), dołączyć do niego pageToken i dzielić na strony wszystkie kolejne żądania, aż znajdziesz na ostatniej stronie kolejny syncToken. Pamiętaj, by zapisać ten zasób (syncToken) na potrzeby następnego żądania synchronizacji w przyszłości.

Oto przykładowe zapytania w przypadku przypadków wymagających przyrostowej synchronizacji z podziałem na strony:

Pierwotne zapytanie

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

// Result contains the following

"nextPageToken":"CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA",

Pobieram następną stronę

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

Serwer wymaga pełnej synchronizacji

Czasami tokeny synchronizacji są unieważniane przez serwer z różnych powodów, takich jak wygaśnięcie tokenu lub zmiany na powiązanych listach kontroli dostępu (ACL). W takich przypadkach serwer odpowie na żądanie przyrostowe kodem odpowiedzi 410. Powinno to aktywować całkowite wyczyszczenie sklepu klienta i nową pełną synchronizację.

Przykładowy kod

Fragment przykładowego kodu poniżej pokazuje, jak używać tokenów synchronizacji z biblioteką klienta w języku Java. Przy pierwszym wywołaniu metody uruchomienia przeprowadzi ona pełną synchronizację i zapisze token synchronizacji. Przy każdym kolejnym wykonaniu wczyta zapisany token synchronizacji i przeprowadzi synchronizację przyrostową.

  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.");
  }

Starsza wersja synchronizacji

W przypadku kolekcji zdarzeń możesz przeprowadzić synchronizację w starszy sposób – wystarczy zachować wartość zaktualizowanego pola z żądania listy zdarzeń, a następnie pobrać zaktualizowane zdarzenia za pomocą pola modifiedSince. Ta metoda nie jest już zalecana, ponieważ jest bardziej podatna na błędy w przypadku nieodebranych aktualizacji (na przykład jeśli nie wymusza ograniczeń dotyczących zapytań). Ponadto jest dostępny tylko w przypadku wydarzeń.