Skip to content

Conversation

@Hweinstock
Copy link
Contributor

@Hweinstock Hweinstock commented Jan 21, 2025

Problem

  • Installed LSP artifacts remain forever. There is no cleanup effort made.

Solution

Implement the following heuristic:

  • Delete all currently installed delisted versions.
  • Delete all versions that remain, except the most recent 2.

Included in this change is a new utility function partition. partition is like filter, but it produces both the positive and negative result in two separate sublists. See the tests for a simple example.


  • Treat all work as PUBLIC. Private feature/x branches will not be squash-merged at release time.
  • Your code changes must meet the guidelines in CONTRIBUTING.md.
  • License: I confirm that my contribution is made under the terms of the Apache 2.0 license.

@github-actions
Copy link

  • This pull request implements a feat or fix, so it must include a changelog entry (unless the fix is for an unreleased feature). Review the changelog guidelines.
    • Note: beta or "experiment" features that have active users should announce fixes in the changelog.
    • If this is not a feature or fix, use an appropriate type from the title guidelines. For example, telemetry-only changes should use the telemetry type.

@Hweinstock
Copy link
Contributor Author

Hweinstock commented Jan 21, 2025

/runIntegrationTests

@Hweinstock Hweinstock marked this pull request as ready for review January 21, 2025 21:51
@Hweinstock Hweinstock requested review from a team as code owners January 21, 2025 21:51
}
}

private async getDownloadedVersions(downloadDirectory: string): Promise<string[]> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you pull this into a common location so the other language server can use it: https://github.com/aws/aws-toolkit-vscode/blob/feature/amazonqLSP/packages/amazonq/src/lsp/lspInstaller.ts

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 moved it to its own util.ts file to avoid circular dependency. Lmk if there is a better place.

}>
) {
this.versionRange = options?.versionRange ?? new Range(supportedLspServerVersions)
this.shouldCleanUp = options?.cleanUp ?? true
Copy link
Contributor

Choose a reason for hiding this comment

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

is there any case where we would make this false?

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 using this to get greater control in the integ tests, but considering those tests aren't even running, it likely makes sense to remove this bloat for now.

assert.ok(result.includes('1.1.1'))
})

it('deletes delisted versions', async function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe a couple more tests to make sure if we have < 2 versions that everything behaves correctly? I think in that case we would want to keep the latest 2 just in case one gets delisted and we can fall back to the other

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 added 3 new cases.

  • if there are less than 2 remaining versions (after filtering for delisted), we should keep all of them.
  • if there are less than 2 versions overall, we should keep all of the non-delisted ones.
  • if all versions present are delisted, we still shouldn't download it.

Do you think that covers the edge cases with < 2 versions?

if (!onMac) {
this.skip()
}
await fs.delete(LanguageServerResolver.defaultDir, { force: true, recursive: true })
Copy link
Contributor

Choose a reason for hiding this comment

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

is there a way we can mock this path somehow we aren't nuking our language servers when we run this test

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 trying to run them as e2e as possible, but I think for these integ tests the setup will take more work to get right. Right now, I deleted them, and we can re-add in a followup if it seems important.

@@ -0,0 +1,10 @@
/*!
Copy link
Contributor

Choose a reason for hiding this comment

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

These various fetch/download/lsp utils seem potentially applicable to both Toolkit and Q in the future. How much of these util modules are Q-specific? Can most of them live in /core/ ?

Copy link
Contributor

Choose a reason for hiding this comment

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

All the logic for downloading/fetching etc is in core. The only thing that should be in the q lsp folder is the codewhisperer language server resolver and the codewhisperer language server activation

Copy link
Contributor

Choose a reason for hiding this comment

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

oh right this is in core but the amazonq part of core... if it's not q-specific then it could live in shared.

}
}

private isDelisted(manifestVersions: LspVersion[], targetVersion: string): boolean {
Copy link
Contributor

@jpinkney-aws jpinkney-aws Jan 24, 2025

Choose a reason for hiding this comment

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

I think these are still missing from this file as well: https://github.com/aws/aws-toolkit-vscode/blob/feature/amazonqLSP/packages/amazonq/src/lsp/lspInstaller.ts#L21. Since this only does the cleanup for the workspace context language server and not the codewhisperer one

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved it to a general location in core to avoid duplicating.

@Hweinstock
Copy link
Contributor Author

non-web failing tests addressed in #6429

isDelisted(manifestVersions, v)
)
for (const v of delistedVersions) {
await fs.delete(path.join(downloadDirectory, v), { force: true, recursive: true })
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess force=true avoids any potential failures. So we don't need to use .catch() to continue the for-loop on failure.

Copy link
Contributor

@justinmk3 justinmk3 left a comment

Choose a reason for hiding this comment

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

Not a blocker for this PR, but it does look lilke the cleanup module + tests should live in shared/languageServer/ (which should be renamed to shared/lsp/)

@Hweinstock
Copy link
Contributor Author

Updated it so that cleanup code lives in packages/core/src/shared/lsp/utils/cleanup.ts. and tests in packages/core/src/test/shared/lsp/utils/cleanup.test.ts.

@jpinkney-aws jpinkney-aws merged commit 7488e0a into aws:feature/amazonqLSP Jan 28, 2025
17 checks passed
@Hweinstock Hweinstock deleted the lsp/cleanUp branch January 28, 2025 14:41
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