Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How should the "unavailable" status interact with network adapter startup? #155

Open
alexjg opened this issue Aug 27, 2023 · 3 comments
Open

Comments

@alexjg
Copy link
Contributor

alexjg commented Aug 27, 2023

Consider this snippet:

const repo = new Repo({
  network: [new BrowserWebSocketClientAdapter("wss://sync.automerge.org")],
  storage: new IndexedDBStorageAdapter(),
})

const rootDocUrl = `${document.location.hash.substr(1)}`
let handle
if (isValidAutomergeUrl(rootDocUrl)) {
    handle = repo.find(rootDocUrl)
}

This will always create a handle which is unavailable, regardless of whether the sync server actually has the document. When we call repo.find the BrowserWebSocketClientAdapter is still in the process of connecting and so the Repo has no peers. Having no peers and not finding the document in storage the Repo marks the handle as unavailable. Later, the websocket network adapter finishes setting up the connection, but by then the handle is already marked as unavailable and so we don't send a sync message to the newly connected peer for the document in question.

I'm not sure what the solution should be here. Here are a few options which occur to me:

  1. Have a small timeout on the "unavailable" status just to give IO a little time to shake out
  2. Add a "setup" phase to network adapters which we wait for before marking any handles as unavailable. This works for things like the browser websocket adapter where we know that once the adapter is running we will have a peer. For other adapters such a phase would not be needed because there may never be any peers (e.g. a websocket server)
  3. Do nothing and just expect the user to re-request a dochandle if they suspect the network has taken some time to get setup.
@acurrieclark
Copy link
Collaborator

Interesting. I would say the second option is preferable to an arbitrary timeout. Or at the very least have some way of exposing to users that the network is not ready before they request a document.

I would have thought that the current implementation does commence sync for an unavailable doc automatically when a new peer connects. If not, I would say it should anyway?

@alexjg
Copy link
Contributor Author

alexjg commented Aug 27, 2023

We can implement beginning sync for an unavailable document when a new peer connects quite easily. Right now that would still be an awkward API though I think because it sort of makes the "unavailable" status less useful. In the snippet above the user would have to always wait on whenReady with some kind of timeout regardless of whether the document resolved as unavailable because they would still need to wait for the network to start up.

I think instead having a kind of "network ready" state for the whole repo might be what is required. That way the user waits for "network ready" and then if a document is unavailable they know that it's not down to the network waiting to come up.

@pvh
Copy link
Member

pvh commented Oct 10, 2023

I've been fighting with this a little bit lately. In trail-runner network connections can come and go in the frontend as ServiceWorkers get replaced. My solution right now is to block on calling find until I've set up a network connection but I don't think this is necessarily the best approach.

I think the issue here is that "network ready" isn't monotonic (your network might report being online prematurely or might go offline again as you travel through a tunnel) and also you may already have all the data you need locally. find() only returns undefined if you don't have the data yet!

In TEE, @geoffreylitt uses a loading screen to guard against trying to do things before connecting. I don't think that's quite the right approach either but it suggests there may be options here.

One thing I've been meaning to do for a while is to start exposing some kind of explanations for why a document didn't load. Was it that there were no peers, that there were peers but nobody would give you the document, was the file corrupted, or was it a bogus input? So many ways to fail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants