-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: don't hang when sharepolicies return immediately
Problem: when using a SharePolicy (rather than doing some asynchronous work) it was possible for the repo to hang. The symptom of this would be that a repo would never respond to sync messages for a document when a SharePolicy returned a positive response for the document. Why was this happening? When the repo first receives a sync message for a (document, peer) combination it checks whether the SharePolicy allows synchronization with the peer in question. To do this the repo creates a new future (correspoinding to SharePolicy::should_sync) and then puts it in a list of share decisions to poll. The share decisions are then polled on the next run through the event loop. If the repo is in a very quiet loop then no new event occurs to trigger the first poll of the future. Solution: at the end of the repo event loop check if there are any share decisions to poll. If there are, then run the loop again.
- Loading branch information
Showing
3 changed files
with
56 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
extern crate test_utils; | ||
|
||
use std::time::Duration; | ||
|
||
use automerge::transaction::Transactable; | ||
use automerge_repo::Repo; | ||
use test_log::test; | ||
use test_utils::storage_utils::{InMemoryStorage, SimpleStorage}; | ||
|
||
use super::tincans::connect_repos; | ||
|
||
#[test(tokio::test)] | ||
async fn test_create_document_then_change_is_synced() { | ||
let repo2_storage = InMemoryStorage::default(); | ||
// Create two repos. | ||
let repo_1 = Repo::new(Some("repo1".to_string()), Box::new(SimpleStorage)); | ||
let repo_2 = Repo::new(Some("repo2".to_string()), Box::new(repo2_storage.clone())); | ||
|
||
// Run the repos in the background. | ||
let repo_handle_1 = repo_1.run(); | ||
let repo_handle_2 = repo_2.run(); | ||
connect_repos(&repo_handle_1, &repo_handle_2); | ||
|
||
// Spawn a task that creates a document and makes a change to id | ||
let doc_handle = tokio::spawn({ | ||
let repo_handle_1 = repo_handle_1.clone(); | ||
async move { | ||
let document_handle_1 = repo_handle_1.new_document(); | ||
|
||
let repo_id = repo_handle_1.get_repo_id().clone(); | ||
let document_handle_1 = document_handle_1.clone(); | ||
// Edit the document. | ||
document_handle_1.with_doc_mut(|doc| { | ||
let mut tx = doc.transaction(); | ||
tx.put(automerge::ROOT, "repo_id", format!("{}", repo_id)) | ||
.expect("Failed to change the document."); | ||
tx.commit(); | ||
}); | ||
document_handle_1 | ||
} | ||
}) | ||
.await | ||
.unwrap(); | ||
|
||
tokio::time::sleep(Duration::from_millis(1000)).await; | ||
|
||
// Now stop both repos | ||
repo_handle_1.stop().unwrap(); | ||
repo_handle_2.stop().unwrap(); | ||
|
||
assert!(repo2_storage.contains_document(doc_handle.document_id())); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters