Skip to content
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

Add plugin API for handling OutsideLifecycleExceptions. #57

Merged
merged 11 commits into from
May 6, 2017

Conversation

tonycosentini
Copy link
Contributor

@tonycosentini tonycosentini commented Mar 21, 2017

(Addresses #52)

The API is very similar to RxJavaPlugins.

One thing I'm a bit concerned about here - if you're providing your own ScopeProvider or LifecycleScopeProvider, you need to either manually use ScopeUtil or manually call the plugin yourself before throwing anything. It would be nicer if AutoDispose does all of this for you.

@CLAassistant
Copy link

CLAassistant commented Mar 21, 2017

CLA assistant check
All committers have signed the CLA.

/**
* Utility class to inject handlers to certain standard AutoDispose operations.
*/
public class AutoDisposePlugins {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final


/**
* Prevents changing the plugins from then on.
* <p>This allows container-like environments to prevent client messing with plugins.</p>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - nextline the text, no need for the closing paragraph marker

);
}

if (f != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if f is null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out, this method isn't even used, I'm going to remove it.

throw new LifecycleNotStartedException();
LifecycleNotStartedException exception = new LifecycleNotStartedException();
if (AutoDisposePlugins.outsideLifecycleHandler != null) {
AutoDisposePlugins.outsideLifecycleHandler.accept(exception);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this use the API rather than the fields directly?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also shouldn't we do something based if we proceed past accept? Like dispose or something?

}
E endEvent;
try {
endEvent = provider.correspondingEvents()
.apply(lastEvent);
} catch (Exception e) {
if (checkEndBoundary && e instanceof LifecycleEndedException) {
throw e;
if (AutoDisposePlugins.outsideLifecycleHandler != null) {
AutoDisposePlugins.outsideLifecycleHandler.accept((LifecycleEndedException) e);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here with using the API

throw e;
if (AutoDisposePlugins.outsideLifecycleHandler != null) {
AutoDisposePlugins.outsideLifecycleHandler.accept((LifecycleEndedException) e);
return Maybe.empty();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this emit immediately to dispose immediately?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking on this one

@ZacSweers
Copy link
Collaborator

I think ScopeUtil is an ok place for this. It's there to be a utility for people to use, and we'll support it in the first party implementation. Kind of like RxJava plugins - people can reuse them but only built-ins are guaranteed to use them

throw e;
if (AutoDisposePlugins.outsideLifecycleHandler != null) {
AutoDisposePlugins.outsideLifecycleHandler.accept((LifecycleEndedException) e);
return Maybe.empty();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking on this one

@ZacSweers
Copy link
Collaborator

Wait I'm dumb. Maybe.empty() is fine, I was thinking of Maybe.never(). It does need to emit something though, we actually don't do anything on empty currently (but maybe we should?)

@ZacSweers
Copy link
Collaborator

Ping on this

Copy link
Collaborator

@ZacSweers ZacSweers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, let's merge once we get tests

@@ -36,7 +36,8 @@

/**
* Prevents changing the plugins from then on.
* <p>This allows container-like environments to prevent client messing with plugins.</p>
*
Copy link
Collaborator

@ZacSweers ZacSweers Apr 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Keep the <p>

.to(new FlowableScoper<Integer>(provider))
.subscribe(o);

o.assertNotSubscribed();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hzsweers any idea why this would fail? This holds true for all the other types but for Flowable, it doesn't seem like it's the case.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestSubscriber and TestObserver are special/weird cases where they never unsubscribe. I'd just save the Disposable off and verify it's disposed.

@ZacSweers
Copy link
Collaborator

ZacSweers commented Apr 24, 2017

I think the tests could be structured a bit differently. At the end of the day, the behavior is what we're interested in. The way that gets done might be an implementation detail, which this kind of verifies manually now (kind of like mockito but not quite). This is also not a conventional use case of RecordingObserver, since a handler is not really an Observer.

What would you think of making it a more functional test? E.g.

  • set a handler that silently swallows LifecycleEndedException exceptions and verify your stream is just disposed without errors
  • a handler that swallows LifecycleNotStartedException exceptions and verify the stream is disposed without errors
  • a handler that rethrows an alternate exception and verify the stream errored with that exception

Let me know what you think

@ZacSweers
Copy link
Collaborator

Also can you add a bit to the README?

@ZacSweers ZacSweers changed the title [WIP] Add plugin API for handling OutsideLifecycleExceptions. Add plugin API for handling OutsideLifecycleExceptions. Apr 24, 2017
@ZacSweers ZacSweers added this to the 0.2.0 milestone Apr 24, 2017
Copy link
Collaborator

@ZacSweers ZacSweers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@ZacSweers ZacSweers merged commit eda9b63 into master May 6, 2017
@ZacSweers ZacSweers deleted the tc_plugins branch May 6, 2017 23:43
This was referenced May 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants