-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
1.x: new hook management proposal #4007
Conversation
* | ||
* @param <T> the value type | ||
*/ | ||
public final class OnSubscribeOnAssembly<T> implements OnSubscribe<T> { |
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.
👍
👍 // More tests would be great, especially for removing parts of stacktrace, but otherwise LGTM. |
Do you have tips how to fake stacktrace for |
Accept |
If this PR gets a go ahead, I'll do that. |
@hzsweers PTAL |
Will look when I can, but probably won't be until next week due to work projects. |
Also it is possible to merge RxJavaHooks into RxJavaPlugins. It would avoid some confusion when switching to 2.x plugins API. |
Don't you afraid that it'll make API of |
How would it make it more confusing? |
Either we'll need to break current API or add very similar methods to On Wed, 22 Jun 2016, 12:22 Zac Sweers, [email protected] wrote:
|
It's an odd class either way. Plus, I've seen mentioned that few tests actually extend |
Updated with more Javadoc. |
Current coverage is 80.26%
|
I'd like to merge this so we can make progress on the coverage/PMD front (which will indicate what tests are needed for this). Any objections? |
I'll take a good look at it today if you don't mind waiting a few hours |
Sure, take your time. |
/** | ||
* Prevents changing the hook callbacks when set to true. | ||
*/ | ||
/* test */ static volatile boolean lockdown; |
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.
Does this mean it's intended for test-use only?
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.
To test if the lockdown actually works, this has to be locked down but then unlocked to allow other tests setting their hooks after that.
Could you include an example of what the output from |
In the IDE, this is what it looks like when watching the exception (its message):
If a test fails, Eclipse's JUnit window can nicely jump to these sources. |
If necessary, we can remove more lines (such as Observable.xxx()) but they might be helpful while diagnosing problems in RxJava itself. |
I think the trace is fine as it is. Good to see it can pick it up as sources that are jumpable as well. We've been using a sort of 👍 for me as long as setting schedulers dynamically still works. |
All the old hooks and reset still work as this delegates to those by default (their original unit tests still pass). |
Would it be possible to use this new API for the same effect though? (changing schedulers on the fly, mainly for testing purposes) |
You can change the schedulers on the fly via |
Sounds good 👍 |
Thanks for the reviews! |
This PR adds a new, in-between, hook manager class,
RxJavaHooks
that allows runtime hooking ofObservable
,Single
,Completable
andSchedulers
components and is aimed to be more versatile than theRxJavaPlugins
.Since
RxJavaPlugins
is public API, it can't be just removed, therefore,RxJavaHooks
by default delegates to it but that delegation can be completely disabled viaclear()
.Usage
Call the
setOn
methods with an appropriate function to manipulate the object being hooked:You can also get the current hooks via the
getOn
methods, allowing chaining multiple hooks if necessary. Changing and retrieving the hooks are thread safe, although it is recommended you change them in quiet times.Operator writers should usually not call the
onXXX
methods onRxJavaHooks
exceptRxJavaHooks.onError()
; It is useful when they have to signal aThrowable
that can't be delivered to aSubscriber
.Calling
reset()
will restore the original delegation hooks.This PR also features a way of tracking the assembly locations, that is where
Observable.create()
was invoked internally or externally, viaenableAssemblyTracking
. It changes the creation hooks of all 3 base types by adding anOnSubscribeOnAssemblyX
wrapper. This operator will replace the Throwable flowing throughonError
and wraps it via the newAssemblyStackTraceException
.Both the wrapper and the exception contain a string representation of the captured stacktrace, this helps "printing" out that information in a debugging session by simply viewing the field contents.
This tracking can be enabled at any time and affects sequences created afterwards. To stop the tracking, use
resetAssemblyTracking
to restore the default delegate callbacks toRxJavaPlugins
orclearAssemblyTracking
to restore the empty hooks (only affecting theonCreate
hooks).For frameworks, the
RxJavaHooks
can be locked down, preventing changing the hooks.If you are using
RxJavaPlugins
existing features, you don't have to do anything; tests will work as before.Performance impact
A default
RxJavaHooks
incurs a 2-4 level indirection in method calls.onNext
calls are not affected.A clear
RxJavaHooks
incurs a volatile read (very cheap) followed by a branch (predictable).onNext
calls are not affected.A tracking-enabled RxJavaHooks incurs an estimated 1000-3000 cycles overhead for each source creation and operator application. The
AssemblyStackTraceException
itself doesn't fill in its own stacktrace but takes only the captured stacktrace string and has mostly the cost of an object allocation. Due to the in-between nature of tracking,onXXX
calls get through another indirection at each operator. For example,range(1, 5).map(v -> v).filter(v -> true).subscribe()
will have 3 extra layers (one for each.
). I believe these are acceptable overheads because the tracking feature is for tracking down crashes and not performance problems.Discussion
Not all hook methods have been replicated completely on
RxJavaHooks
. For one, I wanted a minimal working prototype that passes existing tests. Second, those that are left out are not even tested (onSubscribeError
,onLift
). If the concept of this PR is accepted, those can be added along with their unit tests. Also further Javadoc will be added in the same case.Names and structure are not set in stone.