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

refactor: [M3-7920, M3-7930] – Refactor VPC queries #10322

Merged

Conversation

dwiley-akamai
Copy link
Contributor

@dwiley-akamai dwiley-akamai commented Mar 27, 2024

Description πŸ“

Refactor the VPC queries to use createQueryKeys from query-key-factory.

The main objective was to achieve parity with existing functionality, although some small enhancements at the margins were done as well.

Changes πŸ”„

  • Use createQueryKeys to generate VPC & subnet query keys
  • Update mock region data to include VPC capability
  • Add new useAllVPCsQuery and use it in VPCPanel.tsx & useVPCConfigInterface.tsx
  • Remove manual uses of vpcQueryKey and subnetQueryKey throughout codebase, notably for various query invalidations
  • Remove unused useSubnetQuery

Target release date πŸ—“οΈ

4/15/24

How to test πŸ§ͺ

Verification steps

Essentially the entire VPC offering in Cloud needs to be tested to ensure nothing has broken with these changes.

  • VPC landing page
    • query for paginated results should refresh upon VPC creation
  • Assign/Unassign Linode flow via drawer accessed from Subnets table
    • should invalidate the paginated VPC, individual VPC, and VPC subnets queries
  • Assigning Linode to VPC via Linode Config dialog
    • all VPC queries should be invalidated
  • Linode Create flow
    • a newly-created linode assigned to a VPC should have the VPC section present in the Linode Detail header
  • Linode Detail page
    • the VPC section in the Linode Detail header should be accurate, and the "IP Addresses" table on the "Network" tab should contain the expected VPC-related IPs
  • Deleting a Linode
    • the 'all' VPCs, paginated VPCs, individual VPC, and VPC subnets queries should be invalidated upon Linode deletion

As an Author I have considered πŸ€”

  • πŸ‘€ Doing a self review
  • ❔ Our contribution guidelines
  • 🀏 Splitting feature into small PRs
  • βž• Adding a changeset
  • πŸ§ͺ Providing/Improving test coverage
  • πŸ” Removing all sensitive information from the code and PR description
  • 🚩 Using a feature flag to protect the release
  • πŸ‘£ Providing comprehensive reproduction steps
  • πŸ“‘ Providing or updating our documentation
  • πŸ•› Scheduling a pair reviewing session
  • πŸ“± Providing mobile support
  • β™Ώ Providing accessibility support

…ConfigInterface.ts; include 'VPCs' as capability for mock regions
…sts.ts + update imports across multiple files
@dwiley-akamai dwiley-akamai added React Query Relating to the transition to use React Query VPC Relating to VPC project labels Mar 27, 2024
@dwiley-akamai dwiley-akamai self-assigned this Mar 27, 2024
Comment on lines 37 to 50
contextQueries: {
subnet: (subnetId: number) => ({
queryFn: () => getSubnet(vpcId, subnetId),
queryKey: null,
}),
subnets: {
paginated: (params: Params = {}, filter: Filter = {}) => ({
queryFn: () => getSubnets(vpcId, params, filter),
queryKey: [params, filter],
}),
},
},
queryFn: () => getVPC(vpcId),
queryKey: [vpcId],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bnussman-akamai Does this look correct to you? For some reason, when I go into useSubnetsQuery and begin refactoring it, I type ...vpcQueries.vpc(vpcID). but _ctx doesn't get picked up on as something that exists on the object.

I pulled an example from the docs,

export const users = createQueryKeys('users', {
  detail: (userId: string) => ({
    contextQueries: {
      likes: {
        queryFn: () => api.getUserLikes(userId),
        queryKey: null,
      },
    },
    queryFn: () => api.getUser(userId),
    queryKey: [userId],
  }),
});

just to test the autocomplete and see if there's a syntax issue, but it successfully picked up on users.detail(userId)._ctx as expected.

Am I overlooking something here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Give this a try

export const vpcQueries = createQueryKeys('vpcs', {
  vpc: (vpcId: number) => ({
    contextQueries: {
      subnets: {
        contextQueries: {
          paginated: (params: Params = {}, filter: Filter = {}) => ({
            queryFn: () => getSubnets(vpcId, params, filter),
            queryKey: [params, filter],
          }),
          subnet: (subnetId: number) => ({
            queryFn: () => getSubnet(vpcId, subnetId),
            queryKey: [subnetId],
          }),
        },
        queryKey: null,
      },
    },
    queryFn: () => getVPC(vpcId),
    queryKey: [vpcId],
  }),
  vpcs: {
    contextQueries: {
      all: {
        queryFn: getAllVPCsRequest,
        queryKey: null,
      },
      paginated: (params: Params = {}, filter: Filter = {}) => ({
        queryFn: () => getVPCs(params, filter),
        queryKey: [params, filter],
      }),
    },
    queryKey: null,
  },
});
  • I added queryKey: [subnetId] to the subnet definition
  • I added more nesting to the subnets queries

…since LinodeEntityDetail.tsx pulls in from that one
…dual VPC, and VPC subnets queries should be invalidated upon Linode deletion
…tUnassignLinodesDrawer.tsx, and SubnetAssignLinodesDrawer.tsx (assigning and unassigning Linodes via the drawer should invalidate the paginated VPC, individual VPC, and VPC subnets queries)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This query previously existed:

export const useSubnetQuery = (vpcID: number, subnetID: number) => {	
  return useQuery<Subnet, APIError[]>(	
    [vpcQueryKey, 'vpc', vpcID, subnetQueryKey, 'subnet', subnetID],	
    () => getSubnet(vpcID, subnetID)	
  );	
};

Most of the original queries were written before actual dev work on the UI began last summer, and it turns out this was never used (there's nothing approximating a Subnet Details page) so I removed it.


import type {
APIError,
DeleteLinodeConfigInterfacePayload,
} from '@linode/api-v4';

type IdsForUnassignLinode = DeleteLinodeConfigInterfacePayload & {
subnetId: number;
interface IdsForUnassignLinode extends DeleteLinodeConfigInterfacePayload {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

match the new convention (see #10309 for more)


import type {
APIError,
DeleteLinodeConfigInterfacePayload,
} from '@linode/api-v4';

type IdsForUnassignLinode = DeleteLinodeConfigInterfacePayload & {
subnetId: number;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nothing at the level of [vpcQueryKey, 'vpc', vpcId, subnetQueryKey, 'subnet', subnetId] was ever used in the actual code so this was superfluous

queryFn: () => getVPC(vpcId),
queryKey: [vpcId],
}),
vpcs: {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This results in "vpcs","vpcs" [...] which I do not like given the redundancy, but I think we have to accept?

Screenshot 2024-04-02 at 3 52 16β€―PM

Copy link
Contributor

Choose a reason for hiding this comment

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

Could we "un-nest" the all and paginated queries?

Like this:

export const vpcQueries = createQueryKeys('vpcs', {
  all: {
    queryFn: getAllVPCsRequest,
    queryKey: null,
  },
  paginated: (params: Params = {}, filter: Filter = {}) => ({
    queryFn: () => getVPCs(params, filter),
    queryKey: [params, filter],
  }),
  vpc: (vpcId: number) => ({
    contextQueries: {
      subnets: {
        contextQueries: {
          paginated: (params: Params = {}, filter: Filter = {}) => ({
            queryFn: () => getSubnets(vpcId, params, filter),
            queryKey: [params, filter],
          }),
          subnet: (subnetId: number) => ({
            queryFn: () => getSubnet(vpcId, subnetId),
            queryKey: [subnetId],
          }),
        },
        queryKey: null,
      },
    },
    queryFn: () => getVPC(vpcId),
    queryKey: [vpcId],
  }),
})

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bnussman-akamai Yes, that works and allows us to clean things up a bit πŸ‘πŸΎ Going to push that change

@dwiley-akamai dwiley-akamai marked this pull request as ready for review April 3, 2024 22:56
@dwiley-akamai dwiley-akamai requested a review from a team as a code owner April 3, 2024 22:56
@dwiley-akamai dwiley-akamai requested review from jdamore-linode, cpathipa and bnussman-akamai and removed request for a team April 3, 2024 22:56
…ng need for contextQueries/_ctx and to clean up the end result of the query key
Copy link

github-actions bot commented Apr 4, 2024

Coverage Report: βœ…
Base Coverage: 81.79%
Current Coverage: 81.8%

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we refactor this hook to use useVPCQuery instead of useAllVPCsQuery? This should be a solid optimization over fetching every single VPC

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We previously used useVPCsQuery here, but I think that would pose an issue for some data on the Linode Detail page (see LinodeEntityDetail.tsx and LinodeIPAddress.tsx) for customers with lots of VPCs if the VPC wasn't on the first page of results?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm proposing we just fetch the singular VPC. I agree useVPCsQuery isn't a reliable way to do this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Whoops, I misread your original comment. Yes, that worked fine from my testing so I pushed the refactor in the most recent commit.

packages/manager/src/queries/vpcs/vpcs.ts Outdated Show resolved Hide resolved
packages/manager/src/queries/vpcs/vpcs.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@bnussman-akamai bnussman-akamai left a comment

Choose a reason for hiding this comment

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

Looking great, just a few more things

packages/manager/src/hooks/useUnassignLinode.ts Outdated Show resolved Hide resolved
@@ -35,6 +22,10 @@ export const useVPCConfigInterface = (linodeId: number) => {
return interfaceWithVPC;
});

const { data: vpcLinodeIsAssignedTo } = useVPCQuery(
configInterfaceWithVPC?.vpc_id ?? -1
Copy link
Contributor

Choose a reason for hiding this comment

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

We might want to disable this query so we don't fetch when there is no VPC interface on a Linode.

Suggested change
configInterfaceWithVPC?.vpc_id ?? -1
configInterfaceWithVPC?.vpc_id ?? -1,
Boolean(configInterfaceWithVPC)

@dwiley-akamai dwiley-akamai requested review from cliu-akamai and removed request for cliu-akamai and jdamore-linode April 9, 2024 15:09
@dwiley-akamai
Copy link
Contributor Author

@cliu-akamai There's an E2E failure for linode-config.spec.ts (failed on the previous run and fails locally) that I haven't been able to diagnose -- could you take a look at that?

@cliu-akamai
Copy link
Contributor

@cliu-akamai There's an E2E failure for linode-config.spec.ts (failed on the previous run and fails locally) that I haven't been able to diagnose -- could you take a look at that?

Sure thing!

@cliu-akamai
Copy link
Contributor

If we stop querying the VPCs when accessing endpoint /linodes/${linodeId}/configurations, we should remove Lines 149 and 304 in linode-config.spec.ts to avoid test failure.

@bnussman-akamai
Copy link
Contributor

Looks like deleting lines 138, 149, 292, and 303 fix the failures. I think this makes sense because of the optimization we made in useVPCConfigInterface. We no longer need to GET /v4/vpcs because we now just fetch the singular VPC using GET /v4/vpcs/:id

I'm happy to push that change if you want me to!

@dwiley-akamai dwiley-akamai requested a review from a team as a code owner April 11, 2024 19:05
@dwiley-akamai dwiley-akamai requested review from cliu-akamai and removed request for a team April 11, 2024 19:05
@dwiley-akamai
Copy link
Contributor Author

Looks like deleting lines 138, 149, 292, and 303 fix the failures. I think this makes sense because of the optimization we made in useVPCConfigInterface. We no longer need to GET /v4/vpcs because we now just fetch the singular VPC using GET /v4/vpcs/:id

Initially it was a bit confusing because queryClient.invalidateQueries(vpcQueries.paginated._def) in LinodeConfigDialog.tsx seemed to correspond with the @getVPCs in the test, but in terms of the actual sequence of interactions it makes sense (that invalidation doesn't happen until the user clicks "Save Changes" and it goes through successfully). So I think we're good on that aspect πŸ‘πŸΎ cc @cliu-akamai

Another point is looking into removing the mockAppendFeatureFlags logic in linode-config.spec.ts since VPC isn't feature flagged anymore. That's not in-scope for this ticket, but commenting those pieces out does make the test fail again locally

Copy link
Contributor

@bnussman-akamai bnussman-akamai left a comment

Choose a reason for hiding this comment

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

Looks great πŸ”₯ Thanks for doing this!

Copy link
Contributor

@cpathipa cpathipa 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 @dwiley-akamai!
confirming on the VPC flow and no regressions found.

@dwiley-akamai
Copy link
Contributor Author

@bnussman-akamai Good catches, those were appropriate invalidations to include. Added in the latest commit

@dwiley-akamai dwiley-akamai merged commit 6bffda4 into linode:develop Apr 15, 2024
18 checks passed
@dwiley-akamai dwiley-akamai deleted the M3-7920-7930-vpc-queries-updates branch April 15, 2024 20:51
mjac0bs pushed a commit to mjac0bs/manager that referenced this pull request Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
React Query Relating to the transition to use React Query VPC Relating to VPC project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants