Ver código fonte

fix(replication): send full Document envelope, not just user payload (v1.7.1)

The leader was broadcasting only `doc->data.dump()` — just the user's
JSON fields. The follower's applyReplicatedEntry then parsed that via
Document::fromJson, which expects the full envelope (id, collection,
data, version, timestamps, encryption state). Document::fromJson reads
`j.value("data", {})` — so the user's payload ended up in the "data
field fallback of itself" and became empty.

Result: replication produced structurally-correct stubs (right _id and
_version) but zero user content. Pre-existing bug from commit a96c168
(2026-02-05), unrelated to v1.7.0 eviction work. Surfaced by the
replication sanity load test added in commit 7b9a08e.

Fix is one line — use doc->toJson() instead of doc->data.dump() on the
leader. Follower code unchanged.

Verified with tests/load_test/run_replication_test.sh:
  before fix: 1000 docs replicated, 0 content matches, 1000 mismatches
  after fix:  1000 docs replicated, 1000 matches, 0 mismatches, 366ms
fszontagh 3 meses atrás
pai
commit
1e570a43b4
2 arquivos alterados com 8 adições e 3 exclusões
  1. 1 1
      VERSION
  2. 7 2
      service/src/database_service.cpp

+ 1 - 1
VERSION

@@ -1 +1 @@
-1.7.0
+1.7.1

+ 7 - 2
service/src/database_service.cpp

@@ -512,11 +512,16 @@ void DatabaseService::setupComponents() {
             switch (eventType) {
                 case EventType::INSERT:
                     entry.set_op(databasepb::OP_INSERT);
-                    if (doc) entry.set_data(doc->data.dump());
+                    // Send the full Document envelope (id, collection, data,
+                    // version, timestamps, encryption state). The follower's
+                    // applyReplicatedEntry uses Document::fromJson() which
+                    // expects this envelope — sending only doc->data silently
+                    // dropped every user field on the other side.
+                    if (doc) entry.set_data(doc->toJson().dump());
                     break;
                 case EventType::UPDATE:
                     entry.set_op(databasepb::OP_UPDATE);
-                    if (doc) entry.set_data(doc->data.dump());
+                    if (doc) entry.set_data(doc->toJson().dump());
                     break;
                 case EventType::DELETE:
                     entry.set_op(databasepb::OP_DELETE);