trap host function to avoid wrong atomically() behavior#3309
Open
trap host function to avoid wrong atomically() behavior#3309
Conversation
Contributor
|
Note that the outer retry was only needed in the example because retryPolicy did not work here (as it was automatically closed, making the error happen outside the retrypolicy region). But I think the changes make sense either way |
Contributor
|
Does it make sense to apply the same "trap when an error bubbles up" to the retry policies? I think it would solve all issues we have there as well |
Contributor
Author
maybe, but I'd like to think that through separately (there is another ticket about that problem) |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Before this change,
atomically { ... }worked in the following way:This was always mostly tested with Rust with
panicsas the failure source, in which case it works well.The problem is in the TS SDK (and Scala) errors are manifested as JS exceptions, thrown out of the atomic region, and only becoming a trap if uncaught on top level.
Until recently (within 2 weeks) the TS
atomicallywas always closing the atomic region, even when the inner promise was failed. This made it completely unusable as in that case during recovery the atomic region is considered successfully closed and the switch-to-live event is not happening. So I changed this before to not close the region in case of a failure, which matches the rust sdk behavior.The problem is that the exception can be caught outside of the atomic region and that's what Maxim's example was doing:
here in case of a failure, the atomic region is NOT closed, but we never trap because we catch the exception and by that we leave the atomic region open which leads to all kind of unwanted behaviors.
I was investigating ways to make this work, it could be probably possible to introduce new oplog entries and host functions to record the exception and close the region with that, and then during replay re-emit the exception so our external retry path gets replayed - I decided this is too hard to do, especially because it requires reconstructing the exception completely, and adding new oplog entries.
So what I did in this PR instead is to never allow exceptions out of the atomically block - which will need to be further documented in a follow-up docs/skills PR - and always trap. To be able to trap in JS without having to bubble the exception to the top, I introduced a trap host function. This way the atomic regions work as intended in all languages.