-
Notifications
You must be signed in to change notification settings - Fork 229
Save query history across restarts #1130
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
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
29c29f9
Save query history across restarts
aeisenberg 7785dfe
Update changelog
aeisenberg 64ac33e
Address comments from PR
aeisenberg 9c27d01
Merge branch 'main' into aeisenberg/save-query-history
aeisenberg ad5c43c
Fix failing tests
aeisenberg cca65e5
Rename and add comment
aeisenberg a7e014a
Merge branch 'main' into aeisenberg/save-query-history
aeisenberg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| import * as fs from 'fs-extra'; | ||
| import * as os from 'os'; | ||
| import * as path from 'path'; | ||
| import { Disposable, ExtensionContext } from 'vscode'; | ||
| import { logger } from './logging'; | ||
|
|
||
| const LAST_SCRUB_TIME_KEY = 'lastScrubTime'; | ||
|
|
||
| type Counter = { | ||
| increment: () => void; | ||
| }; | ||
|
|
||
| /** | ||
| * Registers an interval timer that will periodically check for queries old enought | ||
| * to be deleted. | ||
| * | ||
| * Note that this scrubber will clean all queries from all workspaces. It should not | ||
| * run too often and it should only run from one workspace at a time. | ||
| * | ||
| * Generally, `wakeInterval` should be significantly shorter than `throttleTime`. | ||
| * | ||
| * @param wakeInterval How often to check to see if the job should run. | ||
| * @param throttleTime How often to actually run the job. | ||
| * @param maxQueryTime The maximum age of a query before is ready for deletion. | ||
| * @param queryDirectory The directory containing all queries. | ||
| * @param ctx The extension context. | ||
| */ | ||
| export function registerQueryHistoryScubber( | ||
| wakeInterval: number, | ||
| throttleTime: number, | ||
| maxQueryTime: number, | ||
| queryDirectory: string, | ||
| ctx: ExtensionContext, | ||
|
|
||
| // optional counter to keep track of how many times the scrubber has run | ||
| counter?: Counter | ||
| ): Disposable { | ||
| const deregister = setInterval(scrubQueries, wakeInterval, throttleTime, maxQueryTime, queryDirectory, ctx, counter); | ||
|
|
||
| return { | ||
| dispose: () => { | ||
| clearInterval(deregister); | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| async function scrubQueries( | ||
| throttleTime: number, | ||
| maxQueryTime: number, | ||
| queryDirectory: string, | ||
| ctx: ExtensionContext, | ||
| counter?: Counter | ||
| ) { | ||
| const lastScrubTime = ctx.globalState.get<number>(LAST_SCRUB_TIME_KEY); | ||
| const now = Date.now(); | ||
|
|
||
| // If we have never scrubbed before, or if the last scrub was more than `throttleTime` ago, | ||
| // then scrub again. | ||
| if (lastScrubTime === undefined || now - lastScrubTime >= throttleTime) { | ||
| await ctx.globalState.update(LAST_SCRUB_TIME_KEY, now); | ||
|
|
||
| let scrubCount = 0; // total number of directories deleted | ||
| try { | ||
| counter?.increment(); | ||
| void logger.log('Scrubbing query directory. Removing old queries.'); | ||
| if (!(await fs.pathExists(queryDirectory))) { | ||
| void logger.log(`Cannot scrub. Query directory does not exist: ${queryDirectory}`); | ||
| return; | ||
| } | ||
|
|
||
| const baseNames = await fs.readdir(queryDirectory); | ||
| const errors: string[] = []; | ||
| for (const baseName of baseNames) { | ||
| const dir = path.join(queryDirectory, baseName); | ||
| const scrubResult = await scrubDirectory(dir, now, maxQueryTime); | ||
| if (scrubResult.errorMsg) { | ||
| errors.push(scrubResult.errorMsg); | ||
| } | ||
| if (scrubResult.deleted) { | ||
| scrubCount++; | ||
| } | ||
| } | ||
|
|
||
| if (errors.length) { | ||
| throw new Error(os.EOL + errors.join(os.EOL)); | ||
| } | ||
| } catch (e) { | ||
| void logger.log(`Error while scrubbing queries: ${e}`); | ||
| } finally { | ||
| void logger.log(`Scrubbed ${scrubCount} old queries.`); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| async function scrubDirectory(dir: string, now: number, maxQueryTime: number): Promise<{ | ||
| errorMsg?: string, | ||
| deleted: boolean | ||
| }> { | ||
| const timestampFile = path.join(dir, 'timestamp'); | ||
| try { | ||
| let deleted = true; | ||
| if (!(await fs.stat(dir)).isDirectory()) { | ||
| void logger.log(` ${dir} is not a directory. Deleting.`); | ||
| await fs.remove(dir); | ||
| } else if (!(await fs.pathExists(timestampFile))) { | ||
| void logger.log(` ${dir} has no timestamp file. Deleting.`); | ||
| await fs.remove(dir); | ||
| } else if (!(await fs.stat(timestampFile)).isFile()) { | ||
| void logger.log(` ${timestampFile} is not a file. Deleting.`); | ||
| await fs.remove(dir); | ||
| } else { | ||
| const timestampText = await fs.readFile(timestampFile, 'utf8'); | ||
| const timestamp = parseInt(timestampText, 10); | ||
|
|
||
| if (Number.isNaN(timestamp)) { | ||
| void logger.log(` ${dir} has invalid timestamp '${timestampText}'. Deleting.`); | ||
| await fs.remove(dir); | ||
| } else if (now - timestamp > maxQueryTime) { | ||
| void logger.log(` ${dir} is older than ${maxQueryTime / 1000} seconds. Deleting.`); | ||
| await fs.remove(dir); | ||
| } else { | ||
| void logger.log(` ${dir} is not older than ${maxQueryTime / 1000} seconds. Keeping.`); | ||
| deleted = false; | ||
| } | ||
| } | ||
| return { | ||
| deleted | ||
| }; | ||
| } catch (err) { | ||
| return { | ||
| errorMsg: ` Could not delete '${dir}': ${err}`, | ||
| deleted: false | ||
| }; | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.