همگام سازی منابع به طور موثر

این راهنما نحوه‌ی پیاده‌سازی «همگام‌سازی افزایشی» داده‌های تقویم را شرح می‌دهد. با استفاده از این روش، می‌توانید داده‌های مربوط به تمام مجموعه‌های تقویم را همگام‌سازی کنید و در عین حال در پهنای باند صرفه‌جویی کنید.

فهرست مطالب

نمای کلی

همگام‌سازی افزایشی شامل دو مرحله است:

  1. همگام‌سازی کامل اولیه یک بار در همان ابتدا انجام می‌شود تا وضعیت کلاینت به طور کامل با وضعیت سرور همگام‌سازی شود. کلاینت یک توکن همگام‌سازی دریافت می‌کند که برای تداوم به آن نیاز دارد.

  2. همگام‌سازی افزایشی به طور مکرر انجام می‌شود و کلاینت را با تمام تغییراتی که از زمان همگام‌سازی قبلی رخ داده است، به‌روزرسانی می‌کند. هر بار، کلاینت توکن همگام‌سازی قبلی را که از سرور دریافت کرده است، ارائه می‌دهد و توکن همگام‌سازی جدید را از پاسخ ذخیره می‌کند.

همگام‌سازی کامل اولیه

همگام‌سازی کامل اولیه، درخواست اصلی برای تمام منابع مجموعه‌ای است که می‌خواهید همگام‌سازی کنید. اگر فقط می‌خواهید زیرمجموعه خاصی از منابع را همگام‌سازی کنید، می‌توانید درخواست لیست را با استفاده از پارامترهای درخواست محدود کنید.

در پاسخ به عملیات لیست، فیلدی به نام nextSyncToken خواهید یافت که نشان‌دهنده‌ی یک توکن همگام‌سازی است. باید مقدار nextSyncToken را ذخیره کنید. اگر مجموعه نتایج خیلی بزرگ باشد و پاسخ صفحه‌بندی شود، فیلد nextSyncToken فقط در آخرین صفحه وجود خواهد داشت.

همگام‌سازی افزایشی

همگام‌سازی افزایشی به شما امکان می‌دهد تمام منابعی را که از آخرین درخواست همگام‌سازی تغییر یافته‌اند، بازیابی کنید. برای انجام این کار، باید یک درخواست فهرست با جدیدترین توکن همگام‌سازی خود که در فیلد syncToken مشخص شده است، انجام دهید. به خاطر داشته باشید که نتیجه همیشه شامل ورودی‌های حذف شده خواهد بود، به طوری که کلاینت‌ها این فرصت را دارند که آنها را از حافظه حذف کنند.

در مواردی که تعداد زیادی از منابع از زمان آخرین درخواست همگام‌سازی افزایشی تغییر کرده‌اند، ممکن است به جای syncToken در لیست نتایج، یک pageToken پیدا کنید. در این موارد، باید دقیقاً همان کوئری لیست را که برای بازیابی صفحه اول در همگام‌سازی افزایشی استفاده شد (با همان syncToken ) اجرا کنید، pageToken به آن اضافه کنید و تمام درخواست‌های بعدی را صفحه‌بندی کنید تا syncToken دیگری را در صفحه آخر پیدا کنید. حتماً این syncToken برای درخواست همگام‌سازی بعدی در آینده ذخیره کنید.

در اینجا مثال‌هایی از کوئری‌هایی برای موردی که نیاز به همگام‌سازی صفحه‌بندی‌شده افزایشی دارد، آورده شده است:

پرس و جوی اصلی

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

// Result contains the following

"nextPageToken":"CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA",

بازیابی صفحه بعدی

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

همگام‌سازی کامل مورد نیاز توسط سرور

گاهی اوقات توکن‌های همگام‌سازی توسط سرور نامعتبر می‌شوند، به دلایل مختلف از جمله انقضای توکن یا تغییرات در ACL های مرتبط. در چنین مواردی، سرور به یک درخواست افزایشی با کد پاسخ 410 پاسخ می‌دهد. این باید باعث پاک شدن کامل حافظه کلاینت و یک همگام‌سازی کامل جدید شود.

کد نمونه

قطعه کد نمونه زیر نحوه استفاده از توکن‌های همگام‌سازی (sync tokens) را با کتابخانه کلاینت جاوا نشان می‌دهد. اولین باری که متد run فراخوانی می‌شود، یک همگام‌سازی کامل انجام می‌دهد و توکن همگام‌سازی را ذخیره می‌کند. در هر اجرای بعدی، توکن همگام‌سازی ذخیره شده را بارگذاری کرده و یک همگام‌سازی افزایشی انجام می‌دهد.

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

همگام‌سازی قدیمی

برای مجموعه‌های رویداد، هنوز هم می‌توان همگام‌سازی را به روش قدیمی با حفظ مقدار فیلد به‌روزرسانی‌شده از یک درخواست فهرست رویدادها و سپس استفاده از فیلد modifiedSince برای بازیابی رویدادهای به‌روزرسانی‌شده انجام داد. این رویکرد دیگر توصیه نمی‌شود زیرا در رابطه با به‌روزرسانی‌های از دست رفته (مثلاً اگر محدودیت‌های پرس‌وجو را اعمال نکند) مستعد خطا است. علاوه بر این، فقط برای رویدادها در دسترس است.