-
Notifications
You must be signed in to change notification settings - Fork 1.5k
JAVA-6071 #1885
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
base: main
Are you sure you want to change the base?
JAVA-6071 #1885
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should check other implementations of Examples:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @katcharov, it seems to me that |
Uh oh!
There was an error while loading. Please reload this page.
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 needs to be discussed in-person either during one of our catchup meetings, or at a dedicated meeting (the latter may be a 1on1 meeting).
c.complete(localByteBuf)is eventually called, do we construct the long stack of method calls?completecall in it? Answer: yes.bulkWritecommand with all the documents in the created cursor, but a replicaset responds with only a subset, requiring the driver to executegetMores, which means, the driver does not read enough data via eachAsynchronousChannelStream.readAsyncto cause theStackOverflowError. We have https://jira.mongodb.org/plugins/servlet/desk/portal/13/HELP-88629, but it looks like it should be completely reformulated with our current understanding.Nonetheless
beginAsyncAPI usage here. One of the reasons it was introduced is that implementing callbacks/handlers without it is too error-prone: we still throw exceptions/assertions in callback-based code, and unexpected exceptions are still being thrown, yet we can't practically always properly handle them.beginAsyncAPI usage is impossible, the idea of the fix proposed seems right, though I haven't thoroughly reviewed the change to theBasicCompletionHandler.completedmethod.Alternative ideas:
localHandlerinstead ofc.asHandler()here may solve the issue.beginAsyncAPI won't be able to know that we have "completed"localHandlerin a situation when we do it, andlocalHandlerthrows an exception. This may lead tolocalHandlerbeing "completed" more than once by theAsyncSupplier.finishmethod, which absolutely must not be done. This also leads to not executing any code that is "placed between"thenSupplyandfinish(currently, there is none).localHandler.asCallback()intofinishhere, pass a callback that at first extractslocalHandlerviagetHandlerAndClear, and then completes it. This way we should be able to pass the currentBasicCompletionHandler(this) intogetChannel().read(...)here, similarly to how it is proposed in the current PR. But this approach may have the same problem as a).BasicCompletionHandlerhere, we could re-setBasicCompletionHandler.byteBufReferenceandBaseCompletionHandler.handlerReferenceon the existingBasicCompletionHandler(this) tolocalByteBufandc.asHandler()respectively. This way we will save on creating a newBasicCompletionHandler/ a new stack frame per each chunk of data received.beginAsyncAPI at a higher level thanBasicCompletionHandler.completed. Maybe inAsynchronousChannelStream.readAsync? Will it give us the equivalent guarantees?AsyncFunction/AsyncSupplier.finishsuch that executing all the callbacks in the onion of callbacks we currently build does not require growing the call stack by at least one frame per each callback. I do now know if this is doable, and currently fail to imagine how this could even be achieved.c) and d) seem to be the most promising to me, with d) being very nice and simple, provided that it preserves the existing guarantees, which is an open question.
Uh oh!
There was an error while loading. Please reload this page.
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.
We discussed this with @katcharov and @strogiyotec via Zoom, and the idea we ended up with is neither of the aforementioned. It is closest to a combination of c) and e), but is still quite different. What we should do:
BasicCompletionHandlerand rewriteAsynchronousChannelStream.readAsyncvia thebeginAsyncAPI usingAsyncRunnable.thenRunDoWhileLoopor a similar method.AsyncCallbackLoopandRetryingAsyncCallbackSuppliersuch that the amount of stack memory they consume does not depend on the number of loop iterations / retry attempts.Currently:
SameThreadAsyncFunctionsTestandSeparateThreadAsyncFunctionsTest.SameThreadAsyncFunctionsTestandSeparateThreadAsyncFunctionsTest.The aforementioned test is
P.S.
I selfishly want the AI-assisted solution to turn out incorrect once we inspect the code, because I don't want to lose this battle to AI—it would be sorrowful.At least I didn't lose to the damned AI.P.P.S. I inputted that
—(em dash) above viaoption + shift + -in macOS. It wasn't generated by AI.