Mundarija (24)
- Bu darsda
- 1. Nega bu kerak?
- 2. Qurish yoki tayyorini olish
- 2.1 Tayyor yechimlar xaritasi
- 2.2 Auth: kanalga ruxsat
- 2.3 Mezonlar
- 3. Ziddiyat: oxirgi yozgan yutadi
- 3.1 LWW
- 3.2 Qachon LWW yetarli
- 4. CRDT va Yjs
- 4.1 Nima bu
- 4.2 Kanon tajribasi: oflayn tahrir
- 4.3 Y.Map: maydon darajasida LWW
- 4.4 Narxi: hajm va tombstone
- 5. Yjs ni tarmoqqa ulash
- 6. Ko'p uchraydigan xatolar
- 7. Mashqlar
- 1-mashq (oson): nima tanlaysiz
- 2-mashq (o'rta): G-Counter
- 3-mashq (qiyin): LWW-Map
- 8. Loyiha qadami: kanon tajribasi
- 9. Real ishda
- Xulosa
- Manbalar
Tayyor realtime xizmatlari va CRDT: Centrifugo, Pusher, Ably va Yjs
Qisqacha: O'z realtime serveringiz — ulanishlar, masshtab, presence, tarix — hammasi sizning zimmangizda. Tayyor yechimlar ikki xil: o'zingiz o'rnatadigan server (Centrifugo, Soketi) va bulut xizmati (Pusher, Ably, Supabase Realtime). Ular kanonda sinalmagan — tanlov mezonlari hujjat bo'yicha. Ikkinchi mavzu — ziddiyat: ikki kishi bir matnni oflayn tahrirlasa, "oxirgi yozgan yutadi" (LWW) birining ishini yo'qotadi. CRDT (Yjs) esa ikkalasini birlashtiradi: kanonda "Non olish, sut" va "Bugun: Non sotib olish" → "Bugun: Non sotib olish, sut".
Bu darsda
- O'z serveringiz va tayyor xizmat o'rtasida mezonlar bilan tanlaysiz.
- Centrifugo, Pusher, Ably, Soketi va Supabase Realtime nima ekanini bilasiz.
- LWW nega ma'lumot yo'qotishini kodda ko'rasiz.
- Yjs bilan oflayn tahrirni birlashtirish natijasini va narxini (bayt, tombstone) o'qiysiz.
- O'zingiz eng sodda CRDT'larni (G-Counter, LWW-Map) yozasiz.
Oldin bilishingiz kerak: Realtime'ni masshtablash, Amaliyot: chat va bildirishnomalar, Optimistic concurrency, Managed va serverless Postgres (vendor lock-in).
Oldingi darsda chatni o'zimiz qurdik va har detalni — saqlash, holatlar, oflayn — qo'lda hal qildik. Bugun ikki savol: buni umuman o'zingiz qurishingiz shartmi va bir matnni ikki kishi o'zgartirsa nima bo'ladi?
1. Nega bu kerak?
Jasur aka jamoasi uchun ichki ilova qilyapti. Unga uchta realtime funksiya kerak: bildirishnoma, chat va hujjatni birga tahrirlash. Oldingi darslar bo'yicha hisoblaymiz: Socket.IO serveri, Redis adapter, presence TTL bilan, sticky session yoki faqat WebSocket, tarix, monitoring. Bu — alohida xizmat, uni kimdir qo'llab-quvvatlashi kerak.
Ikkinchi muammo — birga tahrir. Aziz poyezdda internetsiz vazifa izohini o'zgartirdi, Dilnoza ofisda o'sha izohni boshqacha o'zgartirdi. Aziz internetga ulanganda kimning matni qoladi?
O'xshatish: to'y. Oshni o'zingiz damlashingiz mumkin (qozon, o'tin, oshpaz — hammasi sizda) yoki oshxonaga buyurtma berasiz (tez, lekin menyu va narx ularniki). Ikkinchi savol — mehmonlar ro'yxati: ikki qarindosh alohida qog'ozga yozgan, ikkalasidan bittasini emas, birlashtirilgan ro'yxatni olish kerak.
2. Qurish yoki tayyorini olish
2.1 Tayyor yechimlar xaritasi
Quyidagilar kanonda sinalmagan — hisob yoki alohida server kerak edi. Tavsif rasmiy hujjat va repolar bo'yicha (2026-10-28 da o'qildi):
| Yechim | Turi | Qisqacha |
|---|---|---|
| Centrifugo | o'zingiz o'rnatasiz | ochiq kodli realtime xabar serveri (Go, Apache-2.0) |
| Soketi | o'zingiz o'rnatasiz | Pusher protokoliga mos ochiq kodli server |
| Pusher Channels | bulut | kanallarga nashr/obuna, private va presence kanallar |
| Ably | bulut | pub/sub, tarix, presence, yetkazish kafolatlari |
| Supabase Realtime | bulut yoki o'zingiz | Postgres o'zgarishlari, broadcast, presence |
Umumiy naqsh — hammasida bir xil: brauzer xizmatga ulanadi (WebSocket yoki SSE), sizning backend'ingiz esa xizmatga HTTP API orqali "shu kanalga shu xabarni yubor" deydi. Ulanishlar, masshtab, qayta ulanish — xizmatning ishi.
flowchart LR
B[Brauzer] -->|WebSocket| X[Realtime xizmat]
B -->|REST| API[Sizning API]
API -->|HTTP publish| X
API -->|auth token| B
API --> DB[(Postgres)]Diagrammaga qarang: sizning API realtime ulanishlarni umuman ushlamaydi. U faqat ikki ish qiladi: foydalanuvchiga xizmatga ulanish uchun token beradi (qaysi kanallarga ruxsat bor) va voqea bo'lganda xizmatga nashr qiladi. Bu Realtime'ni masshtablash darsidagi Redis adapterning "bulutdagi" varianti.
2.2 Auth: kanalga ruxsat
Private kanalga ulanishda mijoz sizning backend'ingizdan imzolangan ruxsat oladi: Pusher'da auth endpoint (ruxsat beradigan maxsus manzil), Centrifugo'da JWT (imzolangan token; uni 28-qismda batafsil o'rganasiz). Mantiq oldingi darslardagidek: "bu foydalanuvchi loyiha:7 kanalini ko'ra oladimi?" — sizning bazangiz hal qiladi. Xizmat faqat imzoni tekshiradi. Imzo kaliti — server sirida (Sirlarni boshqarish), brauzerda emas.
sequenceDiagram
participant B as Brauzer
participant API as Sizning API
participant X as Realtime xizmat
B->>API: loyiha:7 kanaliga ruxsat so'rayman
Note over API: bazada tekshiradi (a'zomi?)
API-->>B: imzolangan token
B->>X: ulanish + token
Note over X: faqat imzoni tekshiradi
X-->>B: obuna tayyor
API->>X: HTTP publish (loyiha:7, xabar)
X->>B: xabarKetma-ketlikka qarang: qaror (ruxsat bormi) doim sizning API'da. Xizmat faqat "imzo to'g'rimi" deb tekshiradi va xabarni yetkazadi.
2.3 Mezonlar
Jadvalda bitta yangi so'z bor: lock-in (bog'lanib qolish) — bir xizmatga shunchalik moslashasizki, boshqasiga o'tish qimmat va uzoq ishga aylanadi.
| Savol | O'zingiz (Socket.IO, SSE) | Tayyor xizmat |
|---|---|---|
| Ulanishlar 1 000 gacha | bitta Node bemalol | ortiqcha bo'lishi mumkin |
| 100 000+ ulanish, ko'p mintaqa | katta ish | asosiy afzalligi |
| Narx | server + vaqtingiz | ulanish/xabar bo'yicha to'lov |
| Ma'lumot qayerda | sizda | xizmat serverlarida |
| Savol | O'zingiz (Socket.IO, SSE) | Tayyor xizmat |
|---|---|---|
| Lock-in | yo'q | protokol va SDK'ga bog'lanasiz |
| Moslashuvchanlik | to'liq | xizmat imkoniyatlari bilan |
| Kim tuzatadi | siz | xizmat jamoasi |
Ikki amaliy eslatma:
- Ma'lumot joylashuvi. Bulut xizmatlar xabarlarni o'z serverlari orqali o'tkazadi. Shaxsiy ma'lumot bo'lsa, O'zbekiston qonunchiligidagi talablarni tekshiring (shaxsiy ma'lumotlar haqidagi qonun — Web scraping Node'da darsida O'RQ-547 eslatilgan). Bu holda o'zingiz o'rnatadigan yechim (Centrifugo, Soketi) mos keladi.
- Loyiha faolligi. Soketi README'sida "maintenance bilan muammolar bo'lgani, yangilanishlar kam" deb yozilgan (2026-10-28). Ochiq kodli vositani tanlashdan oldin oxirgi reliz sanasini va issue'larni tekshiring (Paket tanlash va baholash).
Tekshirib ko'ring: 300 xodimli kompaniya ichki portali uchun bildirishnomalar kerak. Server Toshkentda, ma'lumot tashqariga chiqmasligi kerak. Nima tanlaysiz?
Javob
O'zingiz: SSE (bildirishnoma — bir tomonlama) mavjud Node API'da. 300 ulanish — bitta jarayon uchun kichik yuk, bulut xizmati shart emas, ma'lumot tashqariga chiqmaydi. Ikki tomonlama va katta funksiyalar kerak bo'lsa — o'zingiz o'rnatadigan Centrifugo. Bulut xizmati bu yerda ikki shartga (ma'lumot joylashuvi va hajm) mos emas.
3. Ziddiyat: oxirgi yozgan yutadi
3.1 LWW
Eng sodda qoida — LWW (last-write-wins, oxirgi yozgan yutadi): har yozuvda vaqt bor, birlashtirishda kattasi qoladi.
// LWW: butun matn — bitta qiymat, vaqti kattasi yutadi
function lwwBirlashtir(a, b) {
return a.vaqt >= b.vaqt ? a : b;
}
const asl = "Non olish";
const aziz = { matn: asl + ", sut", vaqt: 1000 };
const dilnoza = { matn: "Bugun: Non sotib olish", vaqt: 1005 };
console.log(lwwBirlashtir(aziz, dilnoza).matn);
console.log(lwwBirlashtir(dilnoza, aziz).matn);Konsolda:
Bugun: Non sotib olish
Bugun: Non sotib olishIkkala tartibda ham natija bir xil — bu yaxshi (nusxalar bir xil holatga keladi). Lekin Azizning ", sut" qo'shimchasi yo'qoldi. Dilnoza 5 ms keyin saqlagani uchun. Yana bir muammo: vaqt qurilma soatidan olinadi, soati oldinda turgan telefon doim "yutadi".
3.2 Qachon LWW yetarli
Vazifa holati, muddati, ustuvorligi kabi bitta qiymatli maydonlar uchun LWW (yoki undan yaxshisi — Optimistic concurrencydagi versiya bilan "o'zgargan bo'lsa, foydalanuvchiga ayt") odatda yetarli. Kanon xulosasi ham shu: "vazifa matni uchun CRDT ortiqcha (optimistik qulf versiya — 26-qism yetarli)". Muammo — matn, uni ikki kishi bir vaqtda yozganda.
4. CRDT va Yjs
4.1 Nima bu
CRDT (Conflict-free Replicated Data Type — ziddiyatsiz takrorlanadigan ma'lumot turi) — har nusxa mustaqil o'zgaradigan va har qanday tartibda birlashtirilganda bir xil natijaga keladigan ma'lumot tuzilmasi. Server "kim to'g'ri" deb hakamlik qilmaydi — matematik qoida hal qiladi.
Matn uchun g'oya: har belgiga noyob ID (kim yozgan + uning hisoblagichi) beriladi va "qaysi belgidan keyin" yozilgani saqlanadi. Ikki kishi turli joylarga yozsa, ikkalasi ham o'z joyida qoladi. O'chirilgan belgi esa butunlay yo'qolmaydi — "o'chirilgan" belgisi bilan qoladi (tombstone), boshqa nusxaning o'zgarishlari unga tayanishi mumkin.
Yjs — JavaScript'dagi eng ko'p ishlatiladigan CRDT kutubxonasi: Y.Text, Y.Map, Y.Array turlari, o'zgarishlarni ixcham ikkilik "update"larga kodlaydi.
4.2 Kanon tajribasi: oflayn tahrir
Kanon kodi (yjs 13.6.33, formatlangan):
import * as Y from "yjs";
const asl = new Y.Doc();
asl.getText("izoh").insert(0, "Non olish");
const boshlangich = Y.encodeStateAsUpdate(asl);
const aziz = new Y.Doc(); Y.applyUpdate(aziz, boshlangich);
const dil = new Y.Doc(); Y.applyUpdate(dil, boshlangich);
aziz.getText("izoh").insert(9, ", sut"); // oxiriga
dil.getText("izoh").insert(0, "Bugun: "); // boshiga
dil.getText("izoh").delete(7 + 4, 5); // "olish" ni o'chiradi
dil.getText("izoh").insert(7 + 4, "sotib olish");
// har biri faqat boshqasida yo'q o'zgarishlarni yuboradi
const uA = Y.encodeStateAsUpdate(aziz, Y.encodeStateVector(dil));
const uD = Y.encodeStateAsUpdate(dil, Y.encodeStateVector(aziz));
Y.applyUpdate(aziz, uD);
Y.applyUpdate(dil, uA);Natijada uchinchi qatorga qarang: birlashgandan keyin ikkala nusxadagi matn va bir xil belgisi.
Aziz (oflayn): "Non olish, sut"
Dilnoza (oflayn): "Bugun: Non sotib olish"
birlashgandan keyin Aziz: "Bugun: Non sotib olish, sut" | Dilnoza: "Bugun: Non sotib olish, sut" | bir xil: true
farq update'lari: Aziz → 21 bayt, Dilnoza → 48 baytNima bo'ldi? Ikkala o'zgarish ham saqlandi: Dilnozaning "Bugun:" va "sotib", Azizning ", sut" — hammasi joyida. Ikkala nusxa bir xil. encodeStateVector — "menda kimdan nechtagacha o'zgarish bor" degan qisqa ro'yxat; unga qarab faqat yetishmayotgan qism yuboriladi — 21 va 48 bayt, butun hujjat emas.
Kanon chiqishidagi keyingi qator ("LWW bo'lganda natija: … yoki … — bittasining o'zgarishi yo'qoladi") o'lchov emas, izoh: kanon skriptida u matn sifatida yozilgan. Yuqoridagi LWW kodimiz buni haqiqatan ko'rsatdi.
4.3 Y.Map: maydon darajasida LWW
Matnda CRDT ikkala o'zgarishni birlashtiradi. Bitta maydonga ikki xil qiymat yozilsa-chi? Ikkalasini "birlashtirib" bo'lmaydi — muddat yoki 28, yoki 30. Kanon:
const m1 = new Y.Doc(); const m2 = new Y.Doc();
m1.getMap("vazifa").set("muddat", "2026-10-28");
m2.getMap("vazifa").set("muddat", "2026-10-30");
m2.getMap("vazifa").set("ustuvorlik", "yuqori");
Y.applyUpdate(m1, Y.encodeStateAsUpdate(m2));
Y.applyUpdate(m2, Y.encodeStateAsUpdate(m1));m1: {"muddat":"2026-10-30","ustuvorlik":"yuqori"} m2: {"muddat":"2026-10-30","ustuvorlik":"yuqori"} — ikkalasida bir xil; maydon darajasida LWWustuvorlik — faqat m2 yozgan, ziddiyat yo'q. muddat da biri yutdi. Qaysi biri? Biz shu tajribani 20 marta qaytardik (yjs 13.6.33, Node 24.21.0) va har safar clientID larni ham yozdik:
{
'bir xil 2026-10-30 (katta clientID: m2)': 12,
'bir xil 2026-10-28 (katta clientID: m1)': 8
}Har safar ikkala nusxa bir xil qiymatga keldi — CRDT kafolati. Lekin g'olib almashib turdi: clientID kattaroq hujjatniki yutdi, clientID esa har new Y.Doc() da tasodifiy. Ya'ni bu "oxirgi yozgan" emas, "tasodifiy, lekin hamma uchun bir xil" g'olib. Bitta maydon uchun foydalanuvchi niyatini CRDT bilmaydi — kerak bo'lsa ziddiyatni foydalanuvchiga ko'rsating.
4.4 Narxi: hajm va tombstone
Kanon o'lchovida "holat" baytlarini matn uzunligi bilan solishtiring:
10 000 insert: 64 ms; holat 10015 bayt (matn 10 000 bayt); V2 kodlash 10029 bayt
1000 marta yozish+o'chirish (natija 5000 belgi): holat 32954 bayt — o'chirilganlar "tombstone" sifatida qoladi- Ketma-ket yozilgan 10 000 belgi — atigi 15 bayt qo'shimcha: Yjs ketma-ket qo'shimchalarni bitta bo'lakka birlashtiradi.
- 1 000 marta "10 belgi yoz, 5 tasini o'chir" — natija 5 000 belgi, lekin holat 32 954 bayt: o'chirilganlar izi qoladi. Ko'p tahrirlangan hujjat vaqt o'tishi bilan o'sadi.
- 64 ms — bitta o'lchov, kanon mashinasida.
Bu raqamlar CRDT bepul emasligini ko'rsatadi. Shuning uchun uni haqiqatan birga tahrirlanadigan joyda ishlating.
5. Yjs ni tarmoqqa ulash
Yjs faqat ma'lumot tuzilmasi — update'larni yetkazish sizning ishingiz. Odatda "provider" ishlatiladi: WebSocket orqali (y-websocket, Hocuspocus serveri), WebRTC orqali yoki IndexedDB'da oflayn saqlash. Server update'larni tarqatadi va hujjatni bazada saqlaydi. Awareness — kursor joyi va kim hozir hujjatda (presence'ning hujjatdagi shakli). Bu providerlar kanonda sinalmagan — Yjs hujjati bo'yicha (2026-10-28).
Boshqa yo'nalish — OT (Operational Transformation): Google Docs tarixan shunga asoslangan. U markaziy server talab qiladi; CRDT esa oflayn va serversiz (peer-to-peer) ishlashga qulayroq. Bugungi ko'p yangi vositalar (Figma o'z variantida, Notion'ning ba'zi qismlari, tldraw) CRDT g'oyalaridan foydalanadi.
6. Ko'p uchraydigan xatolar
| Xato | Natijasi | To'g'risi |
|---|---|---|
| matnni LWW bilan birlashtirish | bir kishining ishi yo'qoladi | CRDT yoki versiya + ogohlantirish |
| har maydonga CRDT | ortiqcha murakkablik va hajm | oddiy maydonga versiya |
| qurilma soatiga ishonish | soati oldindagi "doim yutadi" | server vaqti yoki mantiqiy soat |
| bulut xizmatiga shaxsiy ma'lumot | qonun talablari buziladi | joylashuvni tekshirish |
| xizmat kalitini brauzerga qo'yish | har kim istalgan kanalga yozadi | token faqat backend'da imzolanadi |
| eski ochiq kodli serverni olish | xavfsizlik tuzatishlari yo'q | relizlar va faollikni tekshirish |
7. Mashqlar
Mashqlar kurs/mashqlar/29/43-crdt/ da.
1-mashq (oson): nima tanlaysiz
Har vaziyatga yechim tanlang (o'z SSE/Socket.IO, o'zingiz o'rnatadigan server, bulut xizmati; LWW/versiya yoki CRDT) va sababini bir gapda ayting:
- Startap: 50 000 foydalanuvchili mobil o'yinda reyting jadvali jonli yangilanadi, jamoada 2 dasturchi.
- Vazifaning
muddatmaydonini ikki kishi bir vaqtda o'zgartirdi. - Jamoa hujjatini oflayn ham tahrirlash mumkin bo'lishi kerak.
- Davlat tashkiloti, ma'lumot mamlakatdan chiqmasligi kerak, 20 000 ulanish.
Yechim
- Bulut xizmati (Pusher, Ably) — kichik jamoa, katta ulanish soni; infratuzilmani xizmat oladi.
- Versiya (optimistic concurrency) — bitta qiymat; ikkinchisiga "o'zgargan" deb ayting yoki LWW.
- CRDT (Yjs) — matn, oflayn, birlashtirish kerak.
- O'zingiz o'rnatadigan server (Centrifugo) yoki o'z Socket.IO + Redis — ma'lumot sizning serverlaringizda.
2-mashq (o'rta): G-Counter
Eng sodda CRDT — G-Counter (faqat o'sadigan hisoblagich): har nusxa faqat o'z katagini oshiradi, birlashtirishda har katakning kattasi olinadi, qiymat — kataklar yig'indisi. Telefon 2 marta, noutbuk 3 marta "like" bosdi. Ikkala tartibda birlashtiring va qiymatni chiqaring; keyin birlashgan holatni yana birlashtirib, natija o'zgarmasligini ko'rsating. Ishora: Object.entries, Math.max, spread (Spread va rest operatori).
Yechim
// G-Counter: har nusxa faqat o'z katagini oshiradi
const yangi = () => ({});
const oshir = (s, nusxa, n = 1) =>
({ ...s, [nusxa]: (s[nusxa] ?? 0) + n });
function birlashtir(a, b) {
const natija = { ...a };
for (const [k, v] of Object.entries(b)) {
natija[k] = Math.max(natija[k] ?? 0, v);
}
return natija;
}
const qiymat = (s) => Object.values(s).reduce((x, y) => x + y, 0);
const telefon = oshir(oshir(yangi(), "telefon"), "telefon"); // 2
const noutbuk = oshir(yangi(), "noutbuk", 3); // 3
const t2 = birlashtir(telefon, noutbuk);
const n2 = birlashtir(noutbuk, telefon);
console.log(qiymat(t2), qiymat(n2));
// bir xil holatni qayta yuborish — natija o'zgarmaydi
console.log(qiymat(birlashtir(t2, n2)), qiymat(birlashtir(t2, t2)));Konsolda:
5 5
5 5Uch xususiyat CRDT'ni CRDT qiladi: tartib ahamiyatsiz (t2 va n2 bir xil), takror ahamiyatsiz (birlashtir(t2, t2) o'zgarmadi) va guruhlash ahamiyatsiz. Shuning uchun tarmoq xabarni ikki marta yoki boshqa tartibda yetkazsa ham natija to'g'ri. Nega oddiy son emas? Ikki nusxa "4" va "5" deb yuborsa, ulardan haqiqiy yig'indini (2 + 3) chiqarib bo'lmaydi — kataklar kim nechta qo'shganini saqlaydi.
3-mashq (qiyin): LWW-Map
LWW-Map yozing — har maydon { qiymat, vaqt, nusxa } ko'rinishida. yoz(xarita, maydon, qiymat, vaqt, nusxa) yangi obyekt qaytaradi. birlashtir(x, y) har maydonda vaqti kattasini oladi. Vaqt teng bo'lsa — nusxa nomi kattasini (Yjs clientID kabi deterministik qoida). a: muddat = 2026-10-28 (vaqt 5), matn = "Non olish" (7); b: muddat = 2026-10-30 (vaqt 5), ustuvorlik = "yuqori" (6). Ikkala tartibda birlashtirib, faqat qiymatlarni (maydon nomi bo'yicha saralangan) chiqaring.
Yechim
// LWW-Map: har maydon alohida; teng vaqtda nusxa nomi hal qiladi
function yoz(xarita, maydon, qiymat, vaqt, nusxa) {
return { ...xarita, [maydon]: { qiymat, vaqt, nusxa } };
}
function yutadimi(a, b) {
if (a.vaqt !== b.vaqt) return a.vaqt > b.vaqt;
return a.nusxa > b.nusxa;
}
function birlashtir(x, y) {
const natija = { ...x };
for (const [m, q] of Object.entries(y)) {
if (!natija[m] || yutadimi(q, natija[m])) natija[m] = q;
}
return natija;
}
const korinish = (x) => Object.fromEntries(
Object.entries(x).sort().map(([m, q]) => [m, q.qiymat]));
let a = yoz({}, "muddat", "2026-10-28", 5, "a");
a = yoz(a, "matn", "Non olish", 7, "a");
let b = yoz({}, "muddat", "2026-10-30", 5, "b");
b = yoz(b, "ustuvorlik", "yuqori", 6, "b");
console.log(korinish(birlashtir(a, b)));
console.log(korinish(birlashtir(b, a)));Konsolda:
{ matn: 'Non olish', muddat: '2026-10-30', ustuvorlik: 'yuqori' }
{ matn: 'Non olish', muddat: '2026-10-30', ustuvorlik: 'yuqori' }muddat da vaqt teng (5) — "b" > "a", shuning uchun 30-oktabr. Ikkala tartibda bir xil. Teng vaqtda qo'shimcha qoidasiz birlashtir(a, b) va birlashtir(b, a) turli natija berardi — nusxalar hech qachon bir xil holatga kelmasdi. Kanonning Y.Map tajribasidagi "katta clientID yutadi" — aynan shu qoida.
8. Loyiha qadami: kanon tajribasi
Bu dars loyihaga kod qo'shmaydi. Kanon xulosasi: vazifalar dagi vazifa matni uchun CRDT ortiqcha — 26-qismdagi versiya ustuni bilan optimistik qulf yetarli; realtime esa o'z SseHub imiz bilan. Yjs natijalari — kanon o'lchovidan (IlmHamroh, 2026-10; yjs 13.6.33, Node 24.21.0, 2026-10-27). Y.Map g'olibini 20 marta qaytarish, LWW kodi va mashqlar — biz ishga tushirdik (2026-10-28). Centrifugo, Pusher, Ably, Soketi va Supabase Realtime — sinalmagan.
9. Real ishda
- Figma, Linear, tldraw — hamkorlikda tahrirlash uchun CRDT yoki unga yaqin g'oyalar; Google Docs — tarixan OT.
- Yjs asosidagi muharrirlar: Tiptap, BlockNote; serverlar — Hocuspocus, y-websocket. Automerge — boshqa mashhur CRDT kutubxonasi.
- Pusher, Ably — startaplarda tez boshlash uchun; Centrifugo — o'z serverida katta yukni ushlashni xohlaganlar uchun.
- Intervyuda: "Google Docs'ni qanday loyihalaysiz?", "CRDT va OT farqi?", "LWW qachon yetarli?"
Xulosa
- Realtime'ni o'zingiz qurish — ulanishlar, masshtab, presence va tarix sizda; tayyor xizmat — buni oladi, evaziga narx, lock-in va ma'lumot joylashuvi.
- Centrifugo va Soketi — o'zingiz o'rnatasiz; Pusher, Ably, Supabase Realtime — bulut; hammasi kanonda sinalmagan.
- LWW birining o'zgarishini yo'qotadi: "Non olish, sut" ning ", sut" qismi ketdi.
- Yjs ikkalasini birlashtirdi: "Bugun: Non sotib olish, sut"; farq update'i 21 va 48 bayt.
Y.Mapda bitta maydon — deterministik, lekinclientIDga bog'liq g'olib (20 marta: 12 va 8); tombstone hujjatni o'stiradi.
Keyingi dars: Nega navbat kerak — og'ir ishni so'rovdan ajratib, fonda bajaramiz va javob vaqti qanday qisqarishini o'lchaymiz.
Manbalar
- Centrifugo: https://centrifugal.dev/ va https://github.com/centrifugal/centrifugo — sinalmagan, 2026-10-28 da o'qildi
- Soketi: https://github.com/soketi/soketi — sinalmagan, 2026-10-28 da o'qildi
- Pusher Channels: https://pusher.com/docs/channels/ — sinalmagan
- Ably: https://ably.com/docs — sinalmagan
- Supabase Realtime: https://supabase.com/docs/guides/realtime — sinalmagan
- Yjs: https://docs.yjs.dev/ (Y.Doc, update'lar, providerlar, awareness)
- CRDT haqida: https://crdt.tech/
- Kanon tajribasi (IlmHamroh, 2026-10-27): yjs 13.6.33, Node 24.21.0.
Y.Maptakrori — biz ishga tushirdik (2026-10-28).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!