Skip to content

Reduce contracts and deployments loading time #4233

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

Draft
wants to merge 18 commits into
base: development
Choose a base branch
from

Conversation

samaradel
Copy link
Contributor

@samaradel samaradel commented Jun 12, 2025

Description

Deployments:

  • Load all deployments in parallel
  • Handle migrations in parallel if needed
  • Add grid client cache
  • Add batch processing utility
  • Create grid clients in parallel with caching
  • Load contracts and node IDs in parallel for each machine
  • Process consumptions in batches
  • Process WireGuard configs in batches

Contracts:

  • Node info caching
  • Batch processing for contract normalization, just like Consumptions and WireGuard
  • Parallel data fetching

Changes

Before: deployments loading time takes around 20 to 25 seconds
After: deployments, loading time takes around 15 to 20 seconds

Related Issues

Tested Scenarios

Check deployments loading Time taken in the console for deployments and contracts

Ramez test cases: #4233 (review)

Documentation PR

For UI changes, Please provide the Documentation PR on info_grid

To consider

Preliminary Checks:

  • Preliminary Checks
    • Does it completely address the issue linked?
    • What about edge cases?
    • Does it meet the specified acceptance criteria?
    • Are there any unintended side effects?
    • Does the PR adhere to the team's coding conventions, style guides, and best practices?
    • Does it integrate well with existing features?
    • Does it impact the overall performance of the application?
    • Are there any bottlenecks or slowdowns?
    • Has it been optimized for efficiency?
    • Has it been adequately tested with unit, integration, and end-to-end tests?
    • Are there any known defects or issues?
    • Is the code well-documented?
    • Are changes to documentation reflected in the code?

UI Checks:

  • UI Checks
    • If a UI design is provided/ does it follow it?
    • Does every button work?
    • Is the data displayed logical? Is it what you expected?
    • Does every validation work?
    • Does this interface feel intuitive?
    • What about slow network? Offline?
    • What if the gridproxy/graphql/chain is failing?
    • What would a first time user have a hard time navigating here?

Code Quality Checks:

  • Code Quality Checks
    • Code formatted/linted? Are there unused imports? .. etc
    • Is there redundant/repeated code?
    • Are there conditionals that are always true or always false?
    • Can we write this more concisely?
    • Can we reuse this code? If yes, where?
    • Will the changes be easy to maintain and update in the future?
    • Can this code become too complex to understand for other devs?
    • Can this code cause future integration problems?

Testing Checklist

  • Does it Meet the specified acceptance criteria.
  • Test if changes can affect any other functionality.
  • Tested with unit, integration, and end-to-end tests.
  • Tested the un-happy path and rollback scenarios.
  • Documentation updated to meet the latest changes.
  • Check automated tests working successfully with the changes.
  • Can be covered by automated tests.

General Checklist

  • Tests included
  • Build pass
  • Documentation
  • Code format and docstring
  • Screenshots/Video attached (needed for UI changes)

- Handle migrations in parallel if needed
- Add grid client cache
- Add batch processing utility
- Create grid clients in parallel with caching
- Load contracts and node IDs in parallel for each machine
- Process consumptions in batches
- Process wireguard configs in batches
@samaradel samaradel requested a review from 0oM4R June 22, 2025 12:12
Copy link
Contributor

@0oM4R 0oM4R left a comment

Choose a reason for hiding this comment

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

please use allsettled instead of promise.all for better error handling

@samaradel samaradel marked this pull request as draft June 23, 2025 06:25
@samaradel samaradel requested a review from 0oM4R June 23, 2025 08:04
@samaradel samaradel marked this pull request as ready for review June 23, 2025 08:04
Copy link
Contributor

@0oM4R 0oM4R left a comment

Choose a reason for hiding this comment

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

there are many places that are still using promise.all

please make sure to use promise.allsettled everywhere


const normalizedContracts: NormalizedContract[] = [];
for (const batch of batches) {
const results = await Promise.all(
Copy link
Contributor

Choose a reason for hiding this comment

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

also here still using promise.all

Copy link
Contributor

Choose a reason for hiding this comment

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

@0oM4R
Copy link
Contributor

0oM4R commented Jun 23, 2025

there are other places please make sure to check them as well and replace the promise.all with promise.allsettled

@samaradel samaradel marked this pull request as draft June 23, 2025 09:36
@samaradel samaradel marked this pull request as ready for review June 23, 2025 10:51
@samaradel samaradel requested a review from 0oM4R June 23, 2025 10:51
Copy link
Contributor

@0oM4R 0oM4R left a comment

Choose a reason for hiding this comment

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

partial review will review packages/playground/src/utils/load_deployment.ts
later

Comment on lines 542 to 551
async function getNodeInfoWithCache(nodeIds: number[]) {
const uncachedIds = nodeIds.filter(id => !nodeInfoCache.has(id));
if (uncachedIds.length > 0) {
const newInfo = await getNodeInfo(uncachedIds, []);
for (const [id, info] of Object.entries(newInfo)) {
nodeInfoCache.set(Number(id), info);
}
}
return nodeIds.map(id => nodeInfoCache.get(id));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

  • This function should be moved to the utils, imo
  • Need to add error handling for getNodeInfo
  • I have a concern about invalidating the cache as well

})
.then(res => res[0])
.catch(() => undefined);
} finally {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a catch block; to at least log the errors

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

const results = await Promise.allSettled([
loadVms(grid!),
loadVms(updateGrid(grid!, { projectName: props.projectName.toLowerCase() })),
showAllDeployments.value && props.projectName.toLowerCase() === ProjectName.VM.toLowerCase()
Copy link
Contributor

Choose a reason for hiding this comment

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

we may group the chunk 3 condition in both files into a separate variable then use it here
example

loadChunk3 ? loadVms(updateGrid(grid!, { projectName: "" })) :  Promise.resolve({ count: 0, items: [], failedDeployments: [] }),

Comment on lines 267 to 270
await Promise.allSettled([
chunk1.count > 0 && migrateModule(grid!.gateway),
chunk2.count > 0 && migrateModule(grid!.gateway),
chunk3.count > 0 && migrateModule(grid!.gateway),
Copy link
Contributor

Choose a reason for hiding this comment

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

i do not understand why we are calling the migrateModule threetimes with the same args,
also the && means if a chunk's count is 0, false is passed to Promise.allSettled() instead of a Promise, which works but isn't ideal.
please use

    chunk1.count > 0 ? migrateModule(x) : Promise.resolve(),

Comment on lines 6 to 13
const results: R[] = [];
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
const batchResults = await processFn(batch);
results.push(...batchResults);
}
return results;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

we can run the batches in parallel. Also please add error handling and unit test for it

@samaradel samaradel marked this pull request as draft June 25, 2025 12:10
@samaradel samaradel requested a review from 0oM4R June 25, 2025 14:42
Copy link
Contributor

@0oM4R 0oM4R left a comment

Choose a reason for hiding this comment

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

partal review

@samaradel samaradel marked this pull request as draft July 8, 2025 09:08
- Remove get_nodeInfo_with_cache file and use it as a seperate function
- Create test unit for getNodeInfoWithCache function
- Extract helper functions to reduce the nesting
@samaradel samaradel requested a review from 0oM4R July 8, 2025 19:30
@samaradel samaradel marked this pull request as ready for review July 8, 2025 19:31
@samaradel samaradel marked this pull request as draft July 10, 2025 07:42
@samaradel samaradel marked this pull request as ready for review July 10, 2025 07:48
Copy link
Contributor

@0oM4R 0oM4R left a comment

Choose a reason for hiding this comment

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

in vm the network got loaded twice, any idea

image

@samaradel samaradel marked this pull request as draft July 13, 2025 10:25
@samaradel
Copy link
Contributor Author

@0oM4R fixed now
image

@samaradel samaradel marked this pull request as ready for review July 13, 2025 17:03
@samaradel samaradel requested a review from 0oM4R July 13, 2025 17:03
@0oM4R 0oM4R requested a review from ramezsaeed July 14, 2025 08:19
Copy link
Contributor

@ramezsaeed ramezsaeed left a comment

Choose a reason for hiding this comment

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

Test Scenarios:

  • Test loading contracts time in contract page when have 20 contracts in the account and compare the old time Vs the new time.
  • Test deploy a patch VMs and compare time for list deployment and for contract page.
  • Deploy a Full VM with all networks enabled and compare listing time Vs new time after this PR.
  • Test if we can have a failed deployment and how the list deployments time will react.

Additional tests:

  • Test list deployment time when have VMs in grace period.
  • Test list deployment time when have VMs on offline nodes.

Copy link
Contributor

@0oM4R 0oM4R left a comment

Choose a reason for hiding this comment

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

i have 38 deployment but i can list 41 only
image

on https://dashboard.dev.grid.tf/
image

@0oM4R
Copy link
Contributor

0oM4R commented Jul 15, 2025

I tried to make the deployment listing fail

The error is not accurate, imo
original
Pasted Graphic 2

new branch
Pasted Graphic 1

@0oM4R
Copy link
Contributor

0oM4R commented Jul 15, 2025

listing contract have almost no enhancment

  • listing 74 (node only) contract
  • the original branch 19.877s
  • the new branch 19.094s

list deployment has a significant enhancement

listing 10 micro vm deployments

  • original 35.7s
  • old 71.8155s
    jitsi deployments
  • new branch 43.15s
  • old 75.9s

add 31 name contract so the total now 100 node contract and 31 name contract

  • new branch 38.211 seconds
  • old one 50.6765s

@samaradel samaradel marked this pull request as draft July 16, 2025 07:20
@ramezsaeed
Copy link
Contributor

Tested:

  • Loading time enhanced with 50 VM contracts

@samaradel
Copy link
Contributor Author

samaradel commented Jul 20, 2025

@0oM4R I see the pagination error and loading deployments timeout exist in development, for the contracts I tested with more than 50 contracts, and it takes 13 seconds

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants