-
Notifications
You must be signed in to change notification settings - Fork 509
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
AsyncLaws.thrownInRegisterIsRaiseError cannot be upheld #15
Comments
So, there is an idempotency check (specifically applied here). From a performance standpoint, I'm pretty sure The problem is that if But all that aside… I tend to agree that the law is too restrictive. It basically means that implementors can only implement their types in this way, and I don't think that's what we want to say. So I think you're right that we should remove the law and add it as a test specifically for |
Well, yeah, on top of Java 8 that So yes, it's not IO's implementation I'm complaining about, but this law :-) It would have been helpful to specify an Either in that law ... such that we could specify equivalence with |
Hmm, that's an interesting idea, though I'm not sure how many implementation flaws that would actually catch. A bigger problem though is that the current |
Hi guys,
We cannot have this law, described in this way:
I understand the intention here, but here's the problem: by contract (whether enforced by a law or not), the provided callback function must be called at most once, because that function might trigger side-effects, therefore, at least by convention, we need an idempotency guarantee to keep sanity.
Well, if you say that
F.async[A](_ => throw t)
must be equivalent toF.raiseError(t)
, then you cannot keep this idempotency guarantee without synchronization ... meaning for example to keep some state in anAtomicReference
keeping track of calls (e.g. howPromise#trySuccess
andPromise#tryFailure
are working).Example:
And while that would be cool, I'm pretty sure that you guys don't indent to introduce synchronization in order to achieve such idempotency guarantee, primarily because of performance reasons. In other words, it's better to keep this idempotency as a soft contract ... i.e. in our own implementation, we leave absolutely no room for violating it, but if the user does it, then the behaviour is undefined.
In Monix for such cases I prefer to simply do an
ec.reportFailure(err)
, with thatTask
being non-terminating. In other wordsTask.async(_ => throw ex)
is actually equivalent withTask.never
.I find that acceptable because ... (1) it doesn't blow the current call-stack, (2) it can be treated (with e.g.
timeout
andtimeoutTo
), (3) the exception gets reported by using theExecutionContext
so it has some visibility and (4) I find it normal in this case for the behaviour to be undefined.Users should not allow exceptions to be thrown in
register
. If they do, they should do so at their own risk.Think of this as a tradeoff: it's better to have the behaviour undefined (e.g. either
never
orraiseError
, depending on whatF[_]
can do), than to risk calling that callback twice.The text was updated successfully, but these errors were encountered: