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

UIP-2161 Implement DisposableManagerV3 for UiComponent #91

Merged

Conversation

bencampbell-wf
Copy link
Contributor

Ultimate problem:

Consumers are required to manually deal with lifecycle management within the component lifecycle. This either requires mixing lifecycle management functionality into all of their components or independently managing the lifetime of StreamControllers, `StreamSubscriptions, etc in each component.

How it was fixed:

The DisposableManagerV3 interface has been mixed into the base implementation of UiComponent. This interface proxies all calls to an internal instance of w_common's Disposable. The call to dispose is tied to the componentWillUnmount call ensuring that managed objects are correctly cancelled or concluded when the component is removed from the DOM.

Testing suggestions:

  • The disposable functionality has been exercised in the unit tests. The CI run should pass to confirm this functionality is correct.

Potential areas of regression:

  • An override of react.Component.componentWillUnmount was added to the UiComponent implementation with an annotation that super must be called. There is concern how this may affect current consumers extending UiComponent and are already overriding componentWillUnmount.

FYA: @greglittlefield-wf @aaronlademann-wf @jacehensley-wf @clairesarsam-wf @joelleibow-wf

All components now implement the DisposableManagerV3 interface proxying
management calls to an internal instance of Disposable. This provides
consumers with the set of w_common Disposable methods to ease the
management of various object types.

The disposal of these managed objects is triggered by the unmounting of
the compoment.
@aviary-wf
Copy link

Raven

Number of Findings: 0

@codecov-io
Copy link

codecov-io commented Jun 29, 2017

Codecov Report

Merging #91 into master will increase coverage by 0.05%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master      #91      +/-   ##
==========================================
+ Coverage   94.81%   94.86%   +0.05%     
==========================================
  Files          31       31              
  Lines        1522     1536      +14     
==========================================
+ Hits         1443     1457      +14     
  Misses         79       79

Copy link
Contributor

@aaronlademann-wf aaronlademann-wf left a comment

Choose a reason for hiding this comment

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

@bencampbell-wf Looks really good!

Mainly just wondering if we should allow consumers to subclasses for some of the typed parameters without having to utilize the covariant keyword in their implementations.

I placed a comment on each so we can have a discussion around the merits of covariant for each one (since we may not want to do it for all of them).

_getDisposableProxy().awaitBeforeDispose<T>(future);

@override
Future<T> getManagedDelayedFuture<T>(Duration duration, T callback()) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make the callback param covariant?

_getDisposableProxy().getManagedTimer(duration, callback);

@override
Completer<T> manageCompleter<T>(Completer<T> completer) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make the parameter covariant?

_getDisposableProxy().manageCompleter<T>(completer);

@override
void manageDisposable(Disposable disposable) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make the parameter covariant?

_getDisposableProxy().manageDisposable(disposable);

@override
void manageDisposer(Disposer disposer) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make the parameter covariant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am unsure if/how inheritance would work in the case of typedefs. Does covariant make sense in that case?

Copy link
Contributor

Choose a reason for hiding this comment

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

oh... didn't realize Disposer was a typedef - not a class.

_getDisposableProxy().manageDisposer(disposer);

@override
void manageStreamController(StreamController controller) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make the parameter covariant?

_getDisposableProxy().manageStreamController(controller);

@override
void manageStreamSubscription(StreamSubscription subscription) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make the parameter covariant?

}

//
// END Typed props helpers
Copy link
Contributor

Choose a reason for hiding this comment

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

#nit

//   END DisposableManagerV3 interface implementation

@@ -248,7 +316,7 @@ abstract class UiStatefulComponent<TProps extends UiProps, TState extends UiStat
TState newState() => typedStateFactory({});

//
// END Typed state helpers
// END DisposableManagerV3 interface implementation
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this is accidental - and should be on line 267 instead?

@bencampbell-wf
Copy link
Contributor Author

@aaronlademann-wf I don't see how covariant would hurt anything given the consumption of the DisposableManager interface is internal. At the same time I unable to see a use case where a consumer would need covariant. I'd be glad to make all the parameters covariant if that is a common pattern through the library.

@Workiva Workiva deleted a comment from jacehensley-wf Jun 29, 2017
@greglittlefield-wf
Copy link
Contributor

@aaronlademann-wf I don't think there's a need to use use covariant, and adding it makes it easier for consumers to accidentally/unintentionally violate the liskov substitution principle.

If consumers need covariant, they can add it on their overrides.

Copy link
Contributor

@greglittlefield-wf greglittlefield-wf left a comment

Choose a reason for hiding this comment

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

+1 other than that one comment change. Looks great!! Thanks for implementing this, @bencampbell-wf !!

@@ -248,7 +316,7 @@ abstract class UiStatefulComponent<TProps extends UiProps, TState extends UiStat
TState newState() => typedStateFactory({});

//
// END Typed state helpers
// END Typed props helpers
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this got changed accidentally

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😰

@greglittlefield-wf
Copy link
Contributor

+1

@@ -31,6 +33,7 @@ import 'package:over_react/src/component_declaration/component_type_checking.dar
import 'package:over_react/src/util/ddc_emulated_function_name_bug.dart' as ddc_emulated_function_name_bug;
import 'package:react/react.dart' as react;
import 'package:react/react_client.dart';
import 'package:w_common/disposable.dart';

Choose a reason for hiding this comment

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

should this pull in w_common/disposable_browser.dart instead of just disposable.dart?

Choose a reason for hiding this comment

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

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is dependent on updating the the DisposableManager interface to include the new browser specific utility functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have created RAP-2130 to address this.

@jacehensley-wf
Copy link
Contributor

+1

@aaronlademann-wf
Copy link
Contributor

QA +10

  • Testing instruction
  • Dev +1's
  • Dev/QA +10
  • Unit tests created/updated
  • All unit tests pass
  • Rosie ran/Rosie comment displays expected info
  • Dependency Scan Clean

Merging.

@aaronlademann-wf aaronlademann-wf merged commit da284fd into Workiva:master Jul 5, 2017
@bencampbell-wf bencampbell-wf deleted the uip-2161-disposable-manager branch July 5, 2017 17:13
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.

9 participants