Menyinkronkan resource secara efisien

Panduan ini menjelaskan cara menerapkan "sinkronisasi inkremental" data kalender. Dengan metode ini, Anda dapat menyinkronkan data untuk semua koleksi kalender sekaligus menyimpan bandwidth.

Daftar Isi

Ringkasan

Sinkronisasi inkremental terdiri dari dua tahap:

  1. Sinkronisasi penuh awal dilakukan sekali di awal untuk menyinkronkan status klien secara penuh dengan status server. Klien akan mendapatkan token sinkronisasi yang harus dipertahankan.

  2. Sinkronisasi inkremental dilakukan berulang kali dan memperbarui klien dengan semua perubahan yang terjadi sejak sinkronisasi sebelumnya. Setiap kali, klien menyediakan token sinkronisasi sebelumnya yang diperoleh dari server dan menyimpan token sinkronisasi baru dari respons.

Sinkronisasi penuh awal

Sinkronisasi penuh awal adalah permintaan asli untuk semua resource koleksi yang ingin Anda sinkronkan. Secara opsional, Anda dapat membatasi permintaan daftar menggunakan parameter permintaan jika hanya ingin menyinkronkan subset resource tertentu.

Sebagai respons terhadap operasi daftar, Anda akan menemukan kolom bernama nextSyncToken yang mewakili token sinkronisasi. Anda harus menyimpan nilai nextSyncToken. Jika kumpulan hasilnya terlalu besar dan respons diberi halaman, berarti kolom nextSyncToken hanya ada di halaman terakhir.

Sinkronisasi inkremental

Sinkronisasi inkremental memungkinkan Anda mengambil semua resource yang telah dimodifikasi sejak permintaan sinkronisasi terakhir. Untuk melakukannya, Anda harus membuat permintaan daftar dengan token sinkronisasi terbaru yang ditentukan di kolom syncToken. Perlu diingat bahwa hasilnya akan selalu berisi entri yang dihapus, sehingga klien memiliki kesempatan untuk menghapusnya dari penyimpanan.

Jika sejumlah besar resource telah berubah sejak permintaan sinkronisasi inkremental terakhir, Anda mungkin akan menemukan pageToken, bukan syncToken, dalam hasil daftar. Dalam kasus ini, Anda harus melakukan kueri daftar yang sama persis seperti yang digunakan untuk mengambil halaman pertama dalam sinkronisasi inkremental (dengan syncToken yang sama persis), menambahkan pageToken ke kueri tersebut dan memberi nomor halaman pada semua permintaan berikut sampai Anda menemukan syncToken lain di halaman terakhir. Pastikan untuk menyimpan syncToken ini untuk permintaan sinkronisasi berikutnya di masa mendatang.

Berikut adalah contoh kueri untuk kasus yang memerlukan sinkronisasi inkremental yang diberi nomor halaman:

Kueri asli

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

// Result contains the following

"nextPageToken":"CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA",

Mengambil halaman berikutnya

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

Sinkronisasi penuh diperlukan oleh server

Terkadang, token sinkronisasi dibatalkan oleh server karena berbagai alasan, termasuk akhir masa berlaku token atau perubahan pada ACL terkait. Dalam kasus tersebut, server akan merespons permintaan inkremental dengan kode respons 410. Tindakan ini akan memicu penghapusan total penuh penyimpanan klien dan sinkronisasi penuh yang baru.

Kode contoh

Cuplikan kode contoh di bawah menunjukkan cara menggunakan token sinkronisasi dengan library klien Java. Saat pertama kali dipanggil, metode run akan melakukan sinkronisasi penuh dan menyimpan token sinkronisasi. Pada setiap eksekusi berikutnya, skrip akan memuat token sinkronisasi yang tersimpan dan melakukan sinkronisasi inkremental.

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

Sinkronisasi lama

Untuk pengumpulan peristiwa, sinkronisasi dengan cara lama masih dapat dilakukan dengan mempertahankan nilai kolom yang diperbarui dari permintaan daftar peristiwa, lalu menggunakan kolom modifiedSince untuk mengambil peristiwa yang diperbarui. Pendekatan ini tidak lagi direkomendasikan karena lebih rentan terhadap error sehubungan dengan update yang terlewat (misalnya, jika tidak menerapkan pembatasan kueri). Selain itu, fitur ini hanya tersedia untuk acara.