এই নির্দেশিকায় ক্যালেন্ডার ডেটার "ইনক্রিমেন্টাল সিনক্রোনাইজেশন" কীভাবে বাস্তবায়ন করতে হয় তা বর্ণনা করা হয়েছে। এই পদ্ধতি ব্যবহার করে, আপনি ব্যান্ডউইথ সাশ্রয়ের পাশাপাশি সমস্ত ক্যালেন্ডার কালেকশনের ডেটা সিঙ্কে রাখতে পারবেন।
বিষয়বস্তু
সংক্ষিপ্ত বিবরণ
ক্রমবর্ধমান সিঙ্ক্রোনাইজেশন দুটি পর্যায় নিয়ে গঠিত:
ক্লায়েন্টের অবস্থাকে সার্ভারের অবস্থার সাথে সম্পূর্ণরূপে সিঙ্ক্রোনাইজ করার জন্য একেবারে শুরুতে একবার প্রাথমিক পূর্ণ সিঙ্ক করা হয়। ক্লায়েন্ট একটি সিঙ্ক টোকেন পাবে যা তাকে সংরক্ষণ করতে হবে।
ইনক্রিমেন্টাল সিঙ্ক বারবার সম্পাদিত হয় এবং পূর্ববর্তী সিঙ্কের পর থেকে ঘটে যাওয়া সমস্ত পরিবর্তন দিয়ে ক্লায়েন্টকে আপডেট করে। প্রতিবার, ক্লায়েন্ট সার্ভার থেকে প্রাপ্ত পূর্ববর্তী সিঙ্ক টোকেনটি প্রদান করে এবং রেসপন্স থেকে নতুন সিঙ্ক টোকেনটি সংরক্ষণ করে।
প্রাথমিক পূর্ণ সিঙ্ক
প্রাথমিক পূর্ণ সিঙ্ক হলো কালেকশনের সেই সমস্ত রিসোর্সের জন্য করা মূল অনুরোধ, যা আপনি সিঙ্ক্রোনাইজ করতে চান। আপনি যদি শুধুমাত্র রিসোর্সের একটি নির্দিষ্ট উপসেট সিঙ্ক্রোনাইজ করতে চান, তবে অনুরোধ প্যারামিটার ব্যবহার করে ঐচ্ছিকভাবে তালিকার অনুরোধটি সীমিত করতে পারেন।
লিস্ট অপারেশনের রেসপন্সে আপনি nextSyncToken নামের একটি ফিল্ড পাবেন, যা একটি সিঙ্ক টোকেনকে নির্দেশ করে। আপনাকে nextSyncToken এর ভ্যালুটি স্টোর করতে হবে। যদি রেজাল্ট সেটটি খুব বড় হয় এবং রেসপন্সটি পেজিনেটেড হয়, তাহলে nextSyncToken ফিল্ডটি শুধুমাত্র একদম শেষ পেজেই উপস্থিত থাকে।
ক্রমবর্ধমান সিঙ্ক
ইনক্রিমেন্টাল সিঙ্ক আপনাকে শেষ সিঙ্ক অনুরোধের পর থেকে পরিবর্তিত হওয়া সমস্ত রিসোর্স পুনরুদ্ধার করার সুযোগ দেয়। এটি করার জন্য, আপনাকে syncToken ফিল্ডে আপনার সবচেয়ে সাম্প্রতিক সিঙ্ক টোকেন উল্লেখ করে একটি তালিকা অনুরোধ (list request) করতে হবে। মনে রাখবেন যে, ফলাফলে সর্বদা মুছে ফেলা এন্ট্রিগুলোও থাকবে, যাতে ক্লায়েন্টরা স্টোরেজ থেকে সেগুলো সরিয়ে ফেলার সুযোগ পায়।
In cases where a large number of resources have changed since the last incremental sync request, you may find a pageToken instead of a syncToken in the list result. In these cases you'll need to perform the exact same list query as was used for retrieval of the first page in the incremental sync (with the exact same syncToken ), append the pageToken to it and paginate through all the following requests until you find another syncToken on the last page. Make sure to store this syncToken for the next sync request in the future.
ইনক্রিমেন্টাল পেজিনেটেড সিঙ্ক প্রয়োজন এমন একটি ক্ষেত্রের জন্য এখানে কিছু উদাহরণ কোয়েরি দেওয়া হলো:
মূল প্রশ্ন
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 রেসপন্স কোড পাঠাবে। এর ফলে ক্লায়েন্টের স্টোর সম্পূর্ণরূপে মুছে ফেলা হবে এবং একটি নতুন সম্পূর্ণ সিঙ্ক শুরু হবে।
নমুনা কোড
নিচের নমুনা কোডের অংশটি জাভা ক্লায়েন্ট লাইব্রেরির সাথে সিঙ্ক টোকেন কীভাবে ব্যবহার করতে হয় তা দেখায়। প্রথমবার যখন রান মেথডটি কল করা হয়, তখন এটি একটি সম্পূর্ণ সিঙ্ক সম্পাদন করে এবং সিঙ্ক টোকেনটি সংরক্ষণ করে। পরবর্তী প্রতিটি এক্সিকিউশনে এটি সংরক্ষিত সিঙ্ক টোকেনটি লোড করবে এবং একটি ইনক্রিমেন্টাল সিঙ্ক সম্পাদন করবে।
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."); }
লিগ্যাসি সিঙ্ক্রোনাইজেশন
For event collections, it is still possible to do synchronization in the legacy manner by preserving the value of the updated field from an events list request and then using the modifiedSince field to retrieve updated events. This approach is no longer recommended as it is more error-prone with respect to missed updates (for example if does not enforce query restrictions). Furthermore, it is available only for events.