Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Wait for createDocument to be loaded for subsequent createConnections #822
Wait for createDocument to be loaded for subsequent createConnections #822
Changes from 1 commit
d130031
eccc6e3
f015426
c5de893
672784d
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This map will just grow in memory and always short circuit fetching the document (since it will have the promise in memory).
I'd suggest doing a
.finally
to remove this documentName from the map afterwards to clean it up. We don't want this to act as a cacheThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch here on this growing infinitely!
However, I dont quite follow using
.finally
here. The issue that I am thinking of is that we useloadingDocuments
as the state of whether a doc has been loaded in the form of a promise. The only time it seems acceptable to delete from this map is when we callunloadDocument
. I just pushed a change that removes thePromise<Document>
whenunloadDocument
is called.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jordangarcia I'm unsure that your change got pushed up here, can you check that?
I think that we are thinking of this mapping a bit differently. I am thinking of this map only being useful for "re-using" a fetch to the loading document. This would make it so that two clients requesting the same document while loading would wait for the same document to finish loading.
Client A fetches Doc 1
Client A waits for Doc 1 to load
Client B fetches Doc 1
Client B waits on the same promise as Client A
Doc loads
Client A syncs
Client B syncs
Whereas if I'm understanding you correctly, you want to store the promise here and use this as the source of truth for documents that are loaded or not. When this is what the
documents
map is meant to do.Please let me know your thoughts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My interpretation of the code is that the
this.documents
map isn't quite intended to keep track of "loaded" documents. Since we insert into that map before the document is loaded.this.documents
seems to represent the documents that this hocuspocus instance is managing, regardless of their loading state. Changingthis.documents
to represent documents to be loaded seems like a much bigger API change since many functions rely on this mapping to understand the state of the system.The
loadDocuments
map would be used as the state of the loading documents and a way forcreateDocument
to guarantee a singular doc always being returned (or a promise to the resolved value). The fact thatloadDocuments
sets the created document inthis.documents
then returns the document gaurantees referential equality between the two maps. I do think this may seem a bit fragile to code changes that wouldn't keep these two in sync.The key issue here is that
createDocument
was using thethis.documents
map as a cache of the documents. To be consistent we always wantcreateDocument
to bePromise<Document>
of the loaded document. I dont really see a way around not usingloadingDocuments
as a cache here forcreateDocument
. We could add more state to the system and keep track ofMap<string, boolean>
for whether a document is loaded and then usethis.documents
instead ofthis.loadingDocuments
but that just seems more complex to me.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea this makes sense to me as well.
createDocument
is idempotent and will always return a Promise that resolves to the singular (referential) source of truthDocument
.I do see how this technically is adding more "redundant" state, but I think it's quite clear and simple.
@nperez0111 Curious to hear your thoughts!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into this with @janthurau and we came up with the commit he added on top.
How we were thinking of it is that
loadingDocument
is just a temporary cache for documents that are still in progress of loading and that anyone who calls createDocument will just receive the same promise that is currently loading if there is one.We also maintained the signature of
Promise<Document>
with Promise.resolve ofthis.documents.get(documentName)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good solution as well. Thanks for helping out!
Would love to get this out as soon as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why remove this test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is removed because this behavior should not exist anymore. This test is asserting that if the
onLoadDocument
throws thenprovider2
should still be able to connect to it, which is what we do not want.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the error may be transient, so if it throws it should be able to retry, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not quite sure i follow. Wouldn't it be up to the
HocuspocusProvider
to handle retry logic once the connection fails to be established.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I add the following console logs to the test i see:
I feel like this is not what i would expect this behavior to do in the first place.