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

UI: Ember-data upgrade 5.3.2 prep: use custom service instead of extending ember-data store #28695

Merged
merged 15 commits into from
Oct 17, 2024

Conversation

hellobontempo
Copy link
Contributor

@hellobontempo hellobontempo commented Oct 12, 2024

Description

This PR un-extends the store service and moves lazyPagintedQuery methods to Pagination service to prepare for upgrading to "ember-data": "~5.3.2"


When initially upgrading ember-data and @ember-data/legacy-compat to 5.3.2 we received this error:

router.js:1129 Error while processing route: vault.cluster.index this.store.adapterFor is not a function TypeError: this.store.adapterFor is not a function
    at VersionService.getType (http://localhost:4200/ui/assets/vault.js:64936:41)
    at getType.next (<anonymous>)
  
ember-environment.js:21 Uncaught TypeError: this.store.adapterFor is not a function
    at VersionService.getType (version.js:74:1)
    at getType.next (<anonymous>)
    at GeneratorState.step (generator-state.js:19:53)
    at TaskInstanceExecutor.generatorStep (executor.js:284:42)
    at TaskInstanceExecutor.handleResolvedContinueValue (executor.js:152:27)
    at TaskInstanceExecutor.proceedSync (executor.js:116:12)
    at TaskInstanceExecutor.start (executor.js:54:10)
    at TaskInstance.start (base.js:57:19)
    at refresh.js:27:67
    at Array.forEach (<anonymous>)

Though it's unclear what exactly was causing this error, it was clear the store was failing to compile properly and seemed to trace back to the createCache hook.

image

Deleting our store.js file fixed the build failure and so after some discussion we decided maintaining our custom store extension was become too costly -- every upgrade cycle it required more and more bandaids (#25272, #22838)

We were just extending the store for lazyPaginatedQuery which manages client-side pagination so we opted to move these methods to a custom Pagination service. Although this functionality would probably be better as a decorator (thank you @Monkeychip for the research and suggestion), that refactor is out of scope for this work. (It requires updating all outdated class syntax to use native javascript classes). For now, moving the methods to a separate service was the most feasible, elegant solution. In #28690, addressed some minor cleanup to the store service so updates here would be strictly un-extending the store service and upgrading ember data.

TODO only if you're a HashiCorp employee

  • Backport Labels: If this PR is in the ENT repo and needs to be backported, backport
    to N, N-1, and N-2, using the backport/ent/x.x.x+ent labels. If this PR is in the CE repo, you should only backport to N, using the backport/x.x.x label, not the enterprise labels.
    • If this fixes a critical security vulnerability or severity 1 bug, it will also need to be backported to the current LTS versions of Vault. To ensure this, use all available enterprise labels.
  • ENT Breakage: If this PR either 1) removes a public function OR 2) changes the signature
    of a public function, even if that change is in a CE file, double check that
    applying the patch for this PR to the ENT repo and running tests doesn't
    break any tests. Sometimes ENT only tests rely on public functions in CE
    files.
  • Jira: If this change has an associated Jira, it's referenced either
    in the PR description, commit message, or branch name.
  • RFC: If this change has an associated RFC, please link it in the description.
  • ENT PR: If this change has an associated ENT PR, please link it in the
    description. Also, make sure the changelog is in this PR, not in your ENT PR.

@hellobontempo hellobontempo added this to the 1.19.0-rc milestone Oct 12, 2024
@hellobontempo hellobontempo requested a review from a team as a code owner October 12, 2024 00:04
@github-actions github-actions bot added the hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed label Oct 12, 2024
Copy link

Build Results:
All builds succeeded! ✅

Copy link

github-actions bot commented Oct 12, 2024

CI Results:
All Go tests succeeded! ✅

@hellobontempo
Copy link
Contributor Author

✅ enterprise tests
Screenshot 2024-10-14 at 10 24 02 AM

this.requestManager.use([LegacyNetworkHandler]);
this.requestManager.useCache(CacheHandler);
}
export default class Pagination extends Service {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Name here seemed intuitive, but open to alternatives!

Copy link
Contributor

Choose a reason for hiding this comment

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

I 💚 it.

@@ -83,7 +73,7 @@ export default class StoreService extends Store {
const skipCache = query.skipCache;
// We don't want skipCache to be part of the actual query key, so remove it
delete query.skipCache;
const adapter = this.adapterFor(modelType);
const adapter = this.store.adapterFor(modelType);
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 tried to leave this file alone as much as possible because lazyPaginatedQuery is so widely used and really just updated this to this.store. I'm sure there's lots of cleanup that could be done here but I didn't want to scope creep too much

@hellobontempo hellobontempo changed the title UI: Use custom service instead of extending ember-data store UI: Ember-data upgrade 5.3.2: use custom service instead of extending ember-data store Oct 14, 2024
@@ -38,12 +38,12 @@ export default Route.extend(ListRoute, {
willTransition(transition) {
window.scrollTo(0, 0);
if (!transition || transition.targetName !== this.routeName) {
this.store.clearDataset();
this.pagination.clearDataset();
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 feel like this reads nicely because it's clear we're manipulating the store with a custom method here (and not calling a built-in store method)

modulePrefix,
Resolver,
dependencies: {
export default class KmipEngine extends Engine {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not necessary, but I thought updating this syntax was low lift and quick win removing leaky state potential

@@ -3,16 +3,11 @@
* SPDX-License-Identifier: BUSL-1.1
*/

import Store, { RecordArray } from '@ember-data/store';
import Store from '@ember-data/store';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

At some point we should be able to remove this declaration file and use https://www.npmjs.com/package/@types/ember-data instead, but when I attempted in this PR it didn't work out out of the box so I abandoned for now. (Especially since EmberData 5.4.0-alpha.35 is published with alpha-level support for typescript, so we may be able to avoid installing another dependency all together)

@hellobontempo hellobontempo changed the title UI: Ember-data upgrade 5.3.2: use custom service instead of extending ember-data store UI: Ember-data upgrade 5.3.2 prep: use custom service instead of extending ember-data store Oct 14, 2024

@action
async deleteMessage() {
try {
this.store.clearDataset('config-ui/message');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

typically we call clearDataset after deleting so I don't think this was previously working as expected - went ahead and moved method

@@ -90,8 +90,8 @@ export default class MessagesList extends Component {
@task
*deleteMessage(message) {
try {
this.store.clearDataset('config-ui/message');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

same thing here


lazyCaches = new Map();

setLazyCacheForModel(modelName, key, value) {
const cacheKey = keyForCache(key);
const cache = this.lazyCacheForModel(modelName) || new Map();
cache.set(cacheKey, value);
const modelKey = normalizeModelName(modelName);
Copy link
Contributor

Choose a reason for hiding this comment

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

we did some funny things. Nice clean up

@service secretMountPath;
@service store; // used by @withConfig decorator
Copy link
Contributor

Choose a reason for hiding this comment

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

thanks for the comment

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if the withConfig decorator should inject the store instead if it needs it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep - I almost made that change and can't remember why I didn't 🤔 I think to keep the scope small...because I wanted to change both config decorators and cleanup unneeded store injections

Copy link
Contributor

@Monkeychip Monkeychip left a comment

Choose a reason for hiding this comment

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

Smoke tested (I created 1000) secrets and ran through various areas that code was changed. I really like the name change if anything—much easier to read.

Copy link
Contributor

@zofskeez zofskeez left a comment

Choose a reason for hiding this comment

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

Nice work! Since everything required to make lazyPaginatedQuery function can be achieved by using the public methods on the store service, this seems like a great update to me. 🎉

@service secretMountPath;
@service store; // used by @withConfig decorator
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if the withConfig decorator should inject the store instead if it needs it?

@hellobontempo hellobontempo merged commit 1fbbf9d into main Oct 17, 2024
32 checks passed
@hellobontempo hellobontempo deleted the ui/remove-manual-store-extension branch October 17, 2024 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed pr/no-changelog ui
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants