Package: flutter_gemma_rag_qdrant 1.3.0 with qdrant_edge 0.8.0-dev.3
Platforms tested: Android arm64 (two devices, both Android 16, f2fs, 4 KiB pages), Windows
Two separate findings. The first has a fix; the second I could not explain.
1. EdgeShard.flush() is never called, so nothing survives the process
grep -rn flush over the published package returns nothing. Points added via addDocument / addDocumentWithEmbedding stay in the in-RAM segment, so an index built in one session is gone in the next and the corpus is re-embedded on every launch.
Measured by writing 143 documents (dim 768), then reopening in a new process:
| shutdown before exit |
documents after reopen |
| nothing |
0 |
flush() |
143 |
close() |
143 |
flush() + close() |
143 |
flush() then exit(0) (no Rust drop) |
143 |
Adding the method locally is enough:
// QdrantEdgeClient
Future<void> flush() async {
_checkOpen();
try {
_shard.flush();
} catch (e) {
_rethrow(e);
}
}
// QdrantVectorStore
Future<void> flush() => _serializeLifecycle(_flush);
Future<void> _flush() async {
final c = _client;
if (c == null) return;
await c.flush();
}
Exposing flush() on QdrantVectorStore would be enough for callers to persist once after a bulk index. Note close() calls _shard.unload() (qdrant_edge_client.dart:307), which the SDK declares separately from flush().
2. With flush, one device still cannot reopen a valid shard
Same APK, same code, 143 synthetic documents, flush(), then a new process:
- SM-M336BU (Android 16, arm64-v8a, f2fs, PAGE_SIZE 4096) — reopens, 143 documents.
- SM-S948U1 (Android 16, arm64-v8a, f2fs, PAGE_SIZE 4096) — fails every time:
QdrantException: OperationExceptionEdgeException(Service runtime error:
failed to load segment .../segments/<uuid>: Service runtime error:
Failed to load ID tracker mappings: Service runtime error:
IO Error: No such file or directory (os error 2))
The file it names is present and non-empty:
$ adb shell run-as <pkg> ls -l files/<store>/qdrant_edge_v1/segments/<uuid>
-rw------- 3360 mutable_id_tracker.mappings
-rw------- 1280 mutable_id_tracker.versions
-rw------- 239 segment.json
-rw------- 5 version.info
drwx------ payload_index payload_storage vector_storage
The shard is not corrupt. Pulled off that device with adb exec-out run-as <pkg> tar c and opened on Windows with the same package version, it loads and reports all 143 documents.
Ruled out: corpus size, payload metadata, a preceding failed-open/delete/rebuild cycle, a 15 s delay before reopening, accumulated app state (reproduced after a full uninstall), and app-level code (the failing run drives QdrantVectorStore directly with synthetic vectors — no models, no plugin).
Package:
flutter_gemma_rag_qdrant1.3.0 withqdrant_edge0.8.0-dev.3Platforms tested: Android arm64 (two devices, both Android 16, f2fs, 4 KiB pages), Windows
Two separate findings. The first has a fix; the second I could not explain.
1.
EdgeShard.flush()is never called, so nothing survives the processgrep -rn flushover the published package returns nothing. Points added viaaddDocument/addDocumentWithEmbeddingstay in the in-RAM segment, so an index built in one session is gone in the next and the corpus is re-embedded on every launch.Measured by writing 143 documents (dim 768), then reopening in a new process:
flush()close()flush()+close()flush()thenexit(0)(no Rust drop)Adding the method locally is enough:
Exposing
flush()onQdrantVectorStorewould be enough for callers to persist once after a bulk index. Noteclose()calls_shard.unload()(qdrant_edge_client.dart:307), which the SDK declares separately fromflush().2. With flush, one device still cannot reopen a valid shard
Same APK, same code, 143 synthetic documents,
flush(), then a new process:The file it names is present and non-empty:
The shard is not corrupt. Pulled off that device with
adb exec-out run-as <pkg> tar cand opened on Windows with the same package version, it loads and reports all 143 documents.Ruled out: corpus size, payload
metadata, a preceding failed-open/delete/rebuild cycle, a 15 s delay before reopening, accumulated app state (reproduced after a full uninstall), and app-level code (the failing run drivesQdrantVectorStoredirectly with synthetic vectors — no models, no plugin).