סנכרון יעיל של משאבים

במדריך הזה מוסבר איך להטמיע 'סנכרון מצטבר' של נתוני היומן. באמצעות השיטה הזו אפשר לסנכרן את הנתונים של כל אוספי היומנים תוך שמירה על רוחב הפס.

תוכן עניינים

סקירה

סנכרון מצטבר מורכב משני שלבים:

  1. כדי לסנכרן באופן מלא את מצב הלקוח עם מצב השרת, הסנכרון המלא הראשוני מתבצע פעם אחת בהתחלה. הלקוח יקבל אסימון סנכרון שצריך לשמור עליו.

  2. הסנכרון המצטבר מתבצע שוב ושוב ומעדכן את הלקוח עם כל השינויים שהתרחשו מאז הסנכרון הקודם. בכל פעם, הלקוח מספק את אסימון הסנכרון הקודם שהוא קיבל מהשרת ושומר את אסימון הסנכרון החדש מהתגובה.

סנכרון מלא ראשוני

הסנכרון המלא הראשוני הוא הבקשה המקורית לכל המשאבים של האוסף שרוצים לסנכרן. אם רוצים לסנכרן רק קבוצת משנה ספציפית של משאבים, אפשר להגביל את בקשת הרשימה באמצעות פרמטרים של בקשה.

בתגובה לפעולת הרשימה יופיע שדה בשם nextSyncToken שמייצג אסימון סנכרון. צריך לאחסן את הערך של nextSyncToken. אם קבוצת התוצאות גדולה מדי והתשובה עוברת חלוקה לדפים, השדה nextSyncToken מופיע רק בדף האחרון.

סנכרון מצטבר

סנכרון מצטבר מאפשר לאחזר את כל המשאבים שהשתנו מאז בקשת הסנכרון האחרונה. לשם כך, צריך לשלוח בקשת רשימה עם אסימון הסנכרון האחרון שצוין בשדה syncToken. חשוב לזכור שהתוצאה תמיד תכיל רשומות שנמחקו, כדי שהלקוחות יקבלו הזדמנות להסיר אותן מנפח האחסון.

במקרים שבהם מספר גדול של משאבים השתנו מאז בקשת הסנכרון המצטברת האחרונה, יכול להיות שיופיע pageToken במקום syncToken בתוצאת הרשימה. במקרים כאלה צריך לבצע בדיוק את אותה שאילתת רשימה ששימשה לאחזור הדף הראשון בסנכרון המצטבר (עם אותו 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. הפעולה הזו אמורה לגרום לאיפוס מלא של חנות הלקוח ולסנכרון מלא חדש.

קוד לדוגמה

קטע הקוד לדוגמה שבהמשך מדגים איך להשתמש באסימוני סנכרון עם ספריית הלקוח של Java. בפעם הראשונה שתיקרא לשיטת ההרצה, היא תבצע סנכרון מלא ותאחסן את אסימון הסנכרון. בכל הרצה נוספת, המערכת תטען את אסימון הסנכרון השמור ותבצע סנכרון מצטבר.

  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 כדי לאחזר את האירועים המעודכנים. הגישה הזו לא מומלצת יותר, כי היא יותר מועדת לשגיאות לגבי עדכונים שהוחמצו (לדוגמה, אם לא אוכפת הגבלות על שאילתות). בנוסף, הוא זמין רק לאירועים.