აპლიკაცია მოეპყარით როგორც -ს: ყოველი მოწყობილობა არის ლოკალური . სასწავლო ქმედებები იწერება -ში პლუს append-only -ში (outbox); ხელახლა დაკავშირებისას მოწყობილობა და ბოლო sync-ის შემდეგ. კონფლიქტები წყდება ერთი გლობალური წესით, არამედ .
აპლიკაცია მოეპყარით როგორც -ს: ყოველი მოწყობილობა არის ლოკალური . სასწავლო ქმედებები იწერება -ში პლუს append-only -ში (outbox); ხელახლა დაკავშირებისას მოწყობილობა და ბოლო sync-ის შემდეგ. კონფლიქტები წყდება ერთი გლობალური წესით, არამედ .
აზროვნების მოდელი: წარმოიდგინეთ ისე, როგორც git — ყოველი მოწყობილობა offline-ის დროს ლოკალურად „აკეთებს commit-ს", ხოლო sync არის merge, და არა overwrite.
Device (offline) Server = source of truth
┌──────────────────┐ on reconnect ┌───────────────────────────┐
│ Local DB (SQLite)│ push ops (delta) │ Sync API /sync │
│ + Op log (outbox)│ ─────────────────▶ │ • idempotent by op.id │
│ cursor = lastSeen│ ◀───────────────── │ • merge by semantics │
└──────────────────┘ pull changes>cursor└───────────────────────────┘
Progress DB (Postgres)
ტელეფონის საათები არასანდოა და ორ მოწყობილობას შეუძლია იმავე ჩანაწერის რედაქტირება offline-ში, ამიტომ „last write wins" (LWW) მდუმარედ კარგავს data-ს. გადაწყვიტეთ სემანტიკით:
// op-ს აქვს id -> გამოიყენე იდემპოტენტურად (retries არ ითვლის ორმაგად). clientTs არ არის სანდო.
function mergeProgress(server, op) {
return {
// progress მხოლოდ იზრდება -> max: დაგვიანებული ძველი op არასდროს გადაათრევს უკან
progress: Math.max(server.progress ?? 0, op.progress),
// studiedMs არის დამატებითი counter -> დაამატე delta, ნუ გადააწერ
studiedMs: (server.studiedMs ?? 0) + op.studiedMs,
completedAt: server.completedAt ?? (op.progress >= 1 ? op.clientTs : null),
};
}
აქ, უბრალო LWW მისცემდა უფლებას მოძველებულ მოწყობილობას, რომელიც გვიან sync-ს აკეთებს progress: 0.3-ით, გადაეწერა სერვერის 0.9 → დაკარგული პროგრესი. max-ის აღება და studiedMs-ის შეკრება sync-ს ხდის order-independent-ს — უსაფრთხოა, როცა მილიონობით მოწყობილობა sync-ს აკეთებს დამახინჯებული საათებით.
ინტერვიუერი ამოწმებს, იცით თუ არა, რომ კლიენტის საათები ვერ იქნება სანდო (ანუ არა სუფთა timestamp LWW), აქცევთ თუ არა sync-ს იდემპოტენტურად (op ids), და აკეთებთ თუ არა merge-ს data-ს მნიშვნელობით. სუსტი პასუხი: „გამოიყენე timestamps, last write wins." ძლიერი პასუხი: replica + op log + იდემპოტენტურობა + per-field merge + სერვერი როგორც source of truth — და LWW-ის data-loss ჩავარდნის აშკარად დასახელება.
LWW იაფია, მაგრამ დაკარგვასთან დაკავშირებული; სემანტიკური merge საჭიროებს per-field ფიქრს, მაგრამ არაფერს კარგავს. სრულ CRDT/OT-ს მიმართეთ მხოლოდ მაშინ, როცა გჭირდებათ ნამდვილი collaborative editing (ჩანაწერები, დოკუმენტები) — ის ძვირია, ამიტომ ნუ გამოიყენებთ ყველაფრისთვის.
IT გასაუბრების კითხვების ბიბლიოთეკა დეტალური პასუხებით — Junior-დან Senior-მდე.
შემოწირულობა