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

Upgrade TokenDetectionController to extend BaseControllerV2, StaticIntervalPollingController #3609

Merged

Conversation

MajorLift
Copy link
Contributor

@MajorLift MajorLift commented Dec 1, 2023

Explanation

This upgrades TokenDetectionController to extend BaseControllerV2 and StaticIntervalPollingController as a preparation step for merging TokenDetectionController with DetectTokensController.

References

Changelog

Added

  • TokenListController now exports a TokenListControllerMessenger type (#3609).
  • TokenDetectionController exports types TokenDetectionControllerMessenger, TokenDetectionControllerActions, TokenDetectionControllerGetStateAction, TokenDetectionControllerEvents, TokenDetectionControllerStateChangeEvent (#3609).
  • Add enable and disable methods to TokenDetectionController, which control whether the controller is able to make polling requests or all of its network calls are blocked. (#3609).
    • Note that if the controller is initiated without the disabled constructor option set to false, the enable method will need to be called before the controller can make polling requests in response to subscribed events.

Changed

  • BREAKING: TokenDetectionController is upgraded to extend BaseControllerV2 and StaticIntervalPollingController (#3609).
    • The constructor now expects an options object as its only argument, with required properties messenger, networkClientId, required callbacks onPreferencesStateChange, getBalancesInSingleCall, addDetectedTokens, getTokenState, getPreferencesState, and optional properties disabled, interval, selectedAddress.

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate

@MajorLift MajorLift self-assigned this Dec 1, 2023
@MajorLift MajorLift force-pushed the 231201-token-detection-controller-basecontrollerv2-migration branch 9 times, most recently from dd7ea6c to 4992b15 Compare December 7, 2023 16:24
@MajorLift MajorLift marked this pull request as ready for review December 7, 2023 16:31
@MajorLift MajorLift requested a review from a team as a code owner December 7, 2023 16:31
@MajorLift MajorLift force-pushed the 231201-token-detection-controller-basecontrollerv2-migration branch 9 times, most recently from 64c5308 to b039535 Compare December 11, 2023 16:51
- Add  types`TokenDetectionState`, `TokenDetectionControllerGetStateAction`, `TokenDetectionControllerActions`, `TokenDetectionControllerStateChangeEvent`, `TokenDetectionControllerEvents`, `TokenDetectionControllerMessenger`
- Remove methods that can be replaced with actions/events
- Replace references to `this.config` with `this.state`
- Replace `this.configure()` calls with `this.update()`
@MajorLift MajorLift force-pushed the 231201-token-detection-controller-basecontrollerv2-migration branch from 097bcd4 to acd022f Compare December 20, 2023 15:24
@MajorLift
Copy link
Contributor Author

MajorLift commented Dec 20, 2023

I extracted the tokens-controller changes to a new PR: #3690.

I left the token list controller-messenger export since it's a small, isolated change. (related: should token-list-controller be subscribed to networkDidChange now?)

All tests are passing on this PR now with all suggestions reflected. I think it's ready for a final pass review!

Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Just a couple more comments, but I'm otherwise good with this.

### Changed
- **BREAKING:** `TokenDetectionController` is upgraded to extend `BaseControllerV2` and `StaticIntervalPollingController` ([#3609](https://github.com/MetaMask/core/pull/3609)).
- The constructor now expects an options object as its only argument, with required properties `messenger`, `networkClientId`, required callbacks `onPreferencesStateChange`, `getBalancesInSingleCall`, `getPreferencesState`, and optional properties `interval`, `selectedAddress`. Note that the `config` object is no longer used by the constructor.
- Polling can only be initiated by calling `start` or `startPollingByNetworkClientId` from a controller client. There is no longer an option to automatically start polling when the controller is instantiated.
Copy link
Contributor

Choose a reason for hiding this comment

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

Which option was this?

Copy link
Contributor Author

@MajorLift MajorLift Dec 21, 2023

Choose a reason for hiding this comment

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

Ah, I used "polling" here to include passively calling detectTokens (i.e. executePoll), which is definitely confusing. Also, the disabled option was previously true by default, which makes the current API a breaking change. Thoughts on the following?

Suggested change
- Polling can only be initiated by calling `start` or `startPollingByNetworkClientId` from a controller client. There is no longer an option to automatically start polling when the controller is instantiated.
- **BREAKING:** By default, the controller may now passively call the `detectTokens` method in response to subscribed events. To disable all network requests, initialize the controller with the `disabled` option set to true, or call the `stop` method.

I guess whether to keep this change would depend on the expected behavior of polling controllers upon initialization. If we're going to use a dedicated service for network calls and let it handle blocking outgoing requests, perhaps it makes sense to enable passive updates in the polling controller itself?

But if this is disruptive to the current implementation I can revert the default value for disabled. It will require some changes in the tests, probably including restoring these start calls: 73eccbf.

Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer that we keep the current default, and consider changing this independently even if we do want to. Better to minimize scope of we can.

Copy link
Contributor Author

@MajorLift MajorLift Dec 21, 2023

Choose a reason for hiding this comment

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

One issue with doing that is that the new startPollingByNetworkClientId method is now blocked by default in this controller, and requires the disabled flag to be flipped before it can work.

  • Making the #disabled class field public or adding a setter method seems unsafe and not in keeping with the idea of having this be controlled by a network service,
  • requiring clients or the tests to reinstantiate the entire controller with disabled: false prior to making startPollingByNetworkClientId calls seems like overkill and bad design,
  • requiring start to be called before startPollingByNetworkClientId calls seems redundant and unintuitive,
  • and none of the v2 polling controllers seem to have a disabled property, so lifting the disabled property itself to StaticIntervalPollingController would require more changes that are out of scope.

I'm not sure how to proceed with this off the top of my head. I'll give it some more thought.

Copy link
Member

Choose a reason for hiding this comment

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

I see what you mean, this is a bit tricky. I guess this dilemma was introduced with these new polling functions, but made worse with this change because runtime config modification is no longer possible.

For the CurrencyRateController, the DevEx team decided to deal with this by calling stopAllPolling when the UI closes. So they didn't need to use the disabled state for the newer polling API. But this is problematic because now those polls won't be going anymore when the UI re-opens, even if they might still be needed.

The easiest solution would be to make it possible to update disabled at runtime. I don't know what you meant about that seeming unsafe, nor do I understand what you're referring to by "not in keeping with the idea of having this be controlled by a network service".

Longer-term I'd like us to take these services out of the controller altogether, so that there is never a need to disable the controller. @mcmire and I have also discussed adding a "pause" method to the polling controller, so that they can be paused and unpaused without being deregistered (this idea was from before the service refactor was discussed, I am unsure if we still need this). But both of those ideas seem fairly substantial, I am guessing that we'd be better off trying to land this first, now that this work is already done.

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 was referring to the longer-term solution you mentioned, but I can see that trying to anticipate those changes is premature at this point.

I added a disable and enable method for now: 05cf2bd. Does this seem like a good approach?

Copy link
Member

Choose a reason for hiding this comment

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

Looks reasonable to me!

Copy link
Member

Choose a reason for hiding this comment

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

Could use additional tests for those two new methods though

Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

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

LGTM!

Some missing tests still, but to get this test suite in great shape would require a lot of work, so I'm not sure how high a bar we want to set at this time. I'll leave that for you to decide

Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Great job keeping up with all of the requests 😅 This looks great to me!

@MajorLift
Copy link
Contributor Author

Note on tests for disable and enable:
The last four tests cover the cases disabled: false and disabled: true -> enable().
TODO: add two tests for disabled: false -> disable() -> enable() with active and passive polls in between.

@MajorLift MajorLift merged commit 247890e into main Dec 22, 2023
136 checks passed
@MajorLift MajorLift deleted the 231201-token-detection-controller-basecontrollerv2-migration branch December 22, 2023 19:05
Gudahtt added a commit that referenced this pull request Dec 22, 2023
* origin/main:
  Upgrade `TokenDetectionController` to extend `BaseControllerV2`, `StaticIntervalPollingController` (#3609)
Gudahtt added a commit that referenced this pull request Dec 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Upgrade TokenDetectionController to BaseControllerV2
3 participants