n0-computer / n0-computer/iroh-docs
Docs gets corrupted state when app terminated after doc.set_bytes() success
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 74
- Forks
- 16
- PR merge metrics
- No merged PRs in 30d
Description
Problem:
Doc state is not fully finalized after doc.set_bytes(<..>) completes with success. Seems that data to FsStore is not written completely.
Example case:
- Call
doc.set_bytes(<..>)on Docs withFsStore. awaitfor completion success- Terminate app immediately without waiting for clean shutdown.
- Start application again, and try to get the content for all
Entriesdoc.get_many(query)andstore.get_bytes(hash) - Observe that the entry in Docs exists, but the data in the store not.
This is problematic because docs then try to sync with other endpoints, but noone has that data in a store.
Expectation:
doc.set_bytes(<..>)should complete only when everything is written.
I think this test showcases the issue, where state is not finalized after doc.set_bytes(<..>) return.
Click to expand full code block
On Linux the store file is locked for the second FsStore::load(store_path).await.unwrap(); indefinitely if the original Docs dereferenced and the test never finishes.
#[tokio::test]
async fn test_doc_blob() {
let store_path = "asdf.blobs";
{
let secret_key = { SecretKey::generate(&mut rand::rng()) };
let endpoint = Endpoint::empty_builder(RelayMode::Disabled)
.secret_key(secret_key)
.bind()
.await
.unwrap();
let mdns = MdnsDiscovery::builder().build(endpoint.id()).unwrap();
endpoint.discovery().add(mdns.clone());
let pinger = iroh_ping::Ping::new();
// let blobs_store = MemStore::new();
let blobs_store = FsStore::load(store_path).await.unwrap();
let gossip = Gossip::builder().spawn(endpoint.clone());
let docs = Docs::memory()
.spawn(endpoint.clone(), (*blobs_store).clone(), gossip.clone())
.await
.unwrap();
let _router = Router::builder(endpoint.clone())
.accept(iroh_ping::ALPN, pinger.clone())
.accept(iroh_blobs::ALPN, BlobsProtocol::new(&blobs_store, None))
.accept(iroh_gossip::ALPN, gossip.clone())
.accept(iroh_docs::ALPN, docs.clone())
.spawn();
let doc = docs.create().await.unwrap();
let _hash = doc
.set_bytes(docs.author_default().await.unwrap(), "my_key", "my_value")
.await
.unwrap();
}
let _blobs_store = FsStore::load(store_path).await.unwrap(); // Does not have data
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the provided test with Docs, FsStore::load, and doc.set_bytes, then trace when the store data is persisted and when Docs is shut down. Done means set_bytes returns only after the blob is durable, so reloading FsStore after immediate termination can retrieve the data.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100