096c8347cf
- Thread-safety: locks in LSMTree and Graph engines - Raft network transport: async TCP, serialization, heartbeat, 3-node election test - CI/CD: GitHub Actions workflow - Cleanup: remove dead code, unused imports, build artifacts - New PLAN.md targeting production Web/ERP readiness - 216 tests passing
10 KiB
10 KiB
План за подобряване на BaraDB
Цел
Превърне BaraDB от добър proof-of-concept в солиден, изпълним проект с реална дълбочина на критичните компоненти.
Фаза 1: Честност и стабилна основа (1–2 седмици) ✅ ЗАВЪРШЕНА
1.1 Поправи README.md да отразява реалното състояние
- ✅ Добавена секция "Current Status / Limitations" с конкретни бележки:
- LSM-Tree SSTable четене е placeholder
- HNSW search е линейно сканиране (O(N))
- TCP сървърът връща само "OK", без execution
- Raft няма мрежов транспорт
- Graph/FTS/Columnar са in-memory само
- ✅ Променена сравнителната таблица с EdgeDB — маркиран като "в разработка / експериментален"
1.2 Поправи компилацията на benchmark-ите
- ✅ В
benchmarks/bench_all.nim: заменено(getMonoTime() - start).ticksс(getMonoTime() - start).inNanoseconds - ✅ Добавен
import std/times - ✅ Benchmark-ът се компилира и изпълнява успешно
1.3 Имплементирай реално SSTable четене в storage/lsm.nim
Беше: db.get() намираше ключа в sst.index, но връщаше (true, @[]) — празен масив.
Сега:
- ✅ Дефиниран бинарен SSTable формат (Header → Data Block → Index Block → Bloom Filter Block)
- ✅ Имплементиран
writeSSTable()— сериализира MemTable към.sstфайл - ✅ Имплементиран
loadSSTable()— зарежда съществуващ.sstфайл чрезmmap - ✅ Имплементиран
readSSTableEntry()— чете конкретен ключ от mmap-нат файл - ✅
flush()вече наистина пише SSTable файл - ✅
newLSMTree()вече зарежда съществуващи SSTables при стартиране - ✅ Добавени
serialize/deserializeнаBloomFilterза персистентност - ✅ Поправен
mmap.nimда използваposix.openвместо грешнияsystem.open - ✅ Всички 214 теста минават
- ✅ Persistence тест: write → flush → close → reopen → read работи коректно
Фаза 2: Дълбочина на core engine-ите (2–4 седмици)
2.1 Реализирай истински HNSW search в vector/engine.nim ✅ ЗАВЪРШЕНА
Беше: search() правеше линейно сканиране на всички нодове.
Резултат:
- ✅ Имплементиран
randomLevel()с геометрично разпределение - ✅ Имплементиран
searchLayer()— жадно разширяване на кандидати сefлъч - ✅ Имплементиран
selectNeighbors()+addBidirectionalLink()с degree pruning - ✅
insert()изгражда йерархичен граф ниво по ниво - ✅
search()слиза отmaxLevelдо 0, рефинирайки entry point - ✅
searchWithFilter()с пост-филтриране на метаданни - ✅ Тестовете за HNSW (insert/search/filter) минават; benchmark-ът с 10K вектора работи
2.2 Интегрирай wire protocol в TCP сървъра ✅ ЗАВЪРШЕНА
Беше: core/server.nim връщаше "OK\n" за всяка заявка.
Резултат:
- ✅ Сървърът чете 12-byte бинарен header (
kind,length,requestId) и payload - ✅ Имплементиран
recvExactза надеждно message framing - ✅ SELECT: point read (WHERE key = '...') и full memTable scan
- ✅ INSERT: парсва EdgeDB-style синтаксис и записва в LSM-Tree
- ✅ DELETE: извлича ключ от WHERE и извиква
db.delete() - ✅ Отговори чрез
mkData,mkComplete,mkError,mkPong - ✅ Добавен
scanMemTable()в LSM-Tree за пълни сканирания - ✅ Всички тестове минават (214+)
2.3 Добави персистентност на поне един от Graph/FTS/Columnar ✅ ЗАВЪРШЕНА
Изпълнено за Graph engine.
Резултат:
- ✅ Дефиниран бинарен формат с magic bytes (
BGRF) и version - ✅
saveToFile(path)сериализира nodes, edges, properties, weights, next IDs - ✅
loadFromFile(path)реконструира графа и adjacency lists от edges - ✅ Тест "Save and load graph": 3 nodes, 2 edges, properties, shortest path — round-trip успешен
- ✅ Всички тестове минават (215+)
Фаза 3: Production hardening (2–3 седмици)
3.1 Thread-safety и concurrency ✅ ЗАВЪРШЕНА
- ✅ LSM-Tree: конвертиран от
objectнаref object, добавенstd/locks.Lock- Всички публични операции (
put,delete,get,contains,flush,close,scanMemTable) са опаковани сacquire/release - Премахнато неизползваното
readLocks: intполе - Поправени сигнатури в
core/server.nimотvar LSMTreeнаLSMTree
- Всички публични операции (
- ✅ Graph: добавен
std/locks.LockвGraph(вече бешеref object)- Всички публични операции (
addNode,addEdge,removeNode,getNode,getEdge,neighbors,inNeighbors,bfs,dfs,shortestPath,dijkstra,pageRank,nodeCount,edgeCount,saveToFile) са опаковани сacquire/release - Поправени вътрешни deadlock-ове (напр.
bfs/dfs/shortestPathвече не извикватneighbors, а директен достъп доadjacency)
- Всички публични операции (
- ✅ Stress тестът (
tests/stress_test.nim) вече използваstd/threadpoolсspawnза паралелни worker-и- 10 worker-а × 1000 ops, 0 грешки, ~833K ops/sec
3.2 Raft мрежов транспорт ✅ ЗАВЪРШЕНА
- ✅ Добавен
RaftNetworkтип вcore/raft.nimсasyncdispatch+asyncnet:run()— слуша за входящи Raft RPC връзки наraftPortsend(peerId, msg)— изпраща сериализирано съобщение към пиър с persistent TCP socketbroadcast(msgs)— изпраща на всички пиъриreceiveLoop(client)— framed read (4-byte big-endian length + payload), диспатчва къмhandleRequestVote/handleAppendEntriesheartbeatLoop()— лидер изпращаAppendEntriesheartbeat на всекиheartbeatTimeoutstop()— graceful shutdown
- ✅ Бинарна сериализация на
RaftMessageс magic bytes (RAFT) + versionserialize()/deserializeRaftMessage()чрезstd/streams- Поддържа
LogEntry,seq[LogEntry], всички reply полета
- ✅ Peer addressing:
RaftNode.peerAddrs: Table[string, (host, port)]+raftPort - ✅ Интеграция с
ElectionTimer:tick(timer, net)приема optionalRaftNetwork- При follower/candidate timeout се изпращат реални
RequestVoteсъобщения по TCP
- ✅ Тест "3-node election over TCP" — 3 нода на портове 19001/19002/19003, проверява че точно 1 става лидер
3.3 CI/CD и качество ✅ ЗАВЪРШЕНА
- ✅ Създаден
.github/workflows/ci.yml:- Пуска
nim c --path:src -r tests/test_all.nimна всеки push/PR - Компилира
benchmarks/bench_all.nimв release режим - Компилира и пуска
tests/stress_test.nim - Проверява за
XDeclaredButNotUsedиUnusedImportкато GitHub Actions annotations
- Пуска
- ✅ Създаден
tests/stress_test.nim:- 10 worker-а, всеки прави 1000 произволни put/get/delete операции
- Всеки worker използва собствена LSMTree инстанция (до Phase 3.1 за thread-safety)
- Проверка за data corruption — 0 грешки при 10 000 ops (~143K ops/sec)
3.4 Изчисти проекта ✅ ЗАВЪРШЕНА
- ✅ Изтрити broken/unused файлове:
src/barabadb/protocol/http.nim(unused, 5 compile errors)src/barabadb/protocol/tls.nim(unused, 25 errors, overlaps withssl.nim)src/barabadb/protocol/websocket.nim(unused, 14 errors)src/barabadb.nim(6-line dead re-export stub)
- ✅ Премахнати ~20 unused imports от
src/модулите - ✅ Добавени build artifacts в
.gitignore(*.out, тест/бенчмарк бинарни файлове)
Приоритетна матрица
| Задача | Влияние | Трудност | Приоритет |
|---|---|---|---|
| SSTable реално четене | Критично | Средна | P0 ✅ |
| README честност | Високо | Ниска | P0 ✅ |
| HNSW истински search | Високо | Висока | P1 ✅ |
| Wire protocol в сървъра | Високо | Средна | P1 ✅ |
| Benchmark fix | Ниско | Ниска | P2 ✅ |
| Graph персистентност | Средно | Ниска | P2 ✅ |
| Raft мрежа | Средно | Висока | P2 ✅ |
| Thread-safety | Средно | Средна | P2 ✅ |
| CI/CD | Средно | Ниска | P3 ✅ |
| Изчистване на проекта | Ниско | Ниска | P3 ✅ |
Очакван резултат след изпълнение
- Фаза 1: Проектът е честен, стабилен и benchmark-ите работят. LSM-Tree е валиден key-value store. ✅
- Фаза 2: HNSW работи с реален approximate search. Сървърът изпълнява заявки. Има персистентност. ✅
- Фаза 3: Многонишкова безопасност, CI, по-чист код. ✅
Крайна оценка след плана: от 6.5/10 към 8.5/10.