-
-
Notifications
You must be signed in to change notification settings - Fork 694
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
Add Concurrency Limit to Markdown File Processing for Improved Performance Fixes #3429 #3446
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,7 @@ | ||||||
const fs = require('fs'); | ||||||
const matter = require('gray-matter'); | ||||||
const path = require('path'); | ||||||
const pLimit = require('p-limit'); // Import the p-limit package | ||||||
|
||||||
/** | ||||||
* Checks if a given string is a valid URL. | ||||||
|
@@ -93,12 +94,16 @@ | |||||
} | ||||||
|
||||||
/** | ||||||
* Recursively checks markdown files in a folder and validates their frontmatter. | ||||||
* Recursively checks markdown files in a folder and validates their frontmatter with concurrency control. | ||||||
* @param {string} folderPath - The path to the folder to check. | ||||||
* @param {Function} validateFunction - The function used to validate the frontmatter. | ||||||
* @param {string} [relativePath=''] - The relative path of the folder for logging purposes. | ||||||
* @param {number} concurrencyLimit - The maximum number of files to process concurrently. | ||||||
*/ | ||||||
function checkMarkdownFiles(folderPath, validateFunction, relativePath = '') { | ||||||
function checkMarkdownFiles(folderPath, validateFunction, relativePath = '', concurrencyLimit = 5) { | ||||||
const limit = pLimit(concurrencyLimit); // Limit the concurrency | ||||||
const tasks = []; | ||||||
|
||||||
fs.readdir(folderPath, (err, files) => { | ||||||
if (err) { | ||||||
console.error('Error reading directory:', err); | ||||||
|
@@ -114,33 +119,42 @@ | |||||
return; | ||||||
} | ||||||
|
||||||
fs.stat(filePath, (err, stats) => { | ||||||
if (err) { | ||||||
console.error('Error reading file stats:', err); | ||||||
return; | ||||||
} | ||||||
|
||||||
// Recurse if directory, otherwise validate markdown file | ||||||
if (stats.isDirectory()) { | ||||||
checkMarkdownFiles(filePath, validateFunction, relativeFilePath); | ||||||
} else if (path.extname(file) === '.md') { | ||||||
const fileContent = fs.readFileSync(filePath, 'utf-8'); | ||||||
const { data: frontmatter } = matter(fileContent); | ||||||
|
||||||
const errors = validateFunction(frontmatter); | ||||||
if (errors) { | ||||||
console.log(`Errors in file ${relativeFilePath}:`); | ||||||
errors.forEach(error => console.log(` - ${error}`)); | ||||||
process.exitCode = 1; | ||||||
const task = new Promise((resolve, reject) => { | ||||||
fs.stat(filePath, (err, stats) => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid variable shadowing of 'err' The variable Apply this diff to fix the issue: - fs.stat(filePath, (err, stats) => {
+ fs.stat(filePath, (statErr, stats) => { Also, update the reference to - if (err) {
- reject('Error reading file stats:', err);
+ if (statErr) {
+ reject(new Error(`Error reading file stats: ${statErr.message}`)); 📝 Committable suggestion
Suggested change
🧰 Tools🪛 eslint[error] 123-123: Delete (prettier/prettier) [error] 123-123: 'err' is already declared in the upper scope on line 107 column 29. (no-shadow) |
||||||
if (err) { | ||||||
reject('Error reading file stats:', err); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use Error object when rejecting promises When rejecting a promise, the rejection reason should be an Apply this diff to fix the issue: - reject('Error reading file stats:', err);
+ reject(new Error(`Error reading file stats: ${statErr.message}`));
🧰 Tools🪛 eslint[error] 125-125: Delete (prettier/prettier) [error] 125-125: Expected the Promise rejection reason to be an Error. (prefer-promise-reject-errors) 🪛 GitHub Check: codecov/patch[warning] 122-125: scripts/markdown/check-markdown.js#L122-L125 |
||||||
} else { | ||||||
// Recurse if directory, otherwise validate markdown file | ||||||
if (stats.isDirectory()) { | ||||||
checkMarkdownFiles(filePath, validateFunction, relativeFilePath, concurrencyLimit); | ||||||
} else if (path.extname(file) === '.md') { | ||||||
const fileContent = fs.readFileSync(filePath, 'utf-8'); | ||||||
const { data: frontmatter } = matter(fileContent); | ||||||
|
||||||
const errors = validateFunction(frontmatter); | ||||||
if (errors) { | ||||||
console.log(`Errors in file ${relativeFilePath}:`); | ||||||
errors.forEach(error => console.log(` - ${error}`)); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix missing parentheses in arrow function There is a missing set of parentheses around the parameter in the arrow function, which can cause syntax errors. Apply this diff to fix the issue: - errors.forEach(error => console.log(` - ${error}`));
+ errors.forEach((error) => console.log(` - ${error}`)); 📝 Committable suggestion
Suggested change
🧰 Tools🪛 eslint[error] 137-137: Replace (prettier/prettier) |
||||||
process.exitCode = 1; | ||||||
} | ||||||
} | ||||||
resolve(); | ||||||
} | ||||||
} | ||||||
}); | ||||||
}); | ||||||
|
||||||
// Add task with concurrency limit | ||||||
tasks.push(limit(() => task)); | ||||||
}); | ||||||
|
||||||
// Wait for all tasks to complete | ||||||
Promise.all(tasks).then(() => console.log('All files processed.')); | ||||||
}); | ||||||
} | ||||||
|
||||||
const docsFolderPath = path.resolve(__dirname, '../../markdown/docs'); | ||||||
const blogsFolderPath = path.resolve(__dirname, '../../markdown/blog'); | ||||||
|
||||||
checkMarkdownFiles(docsFolderPath, validateDocs); | ||||||
checkMarkdownFiles(blogsFolderPath, validateBlogs); | ||||||
// Call the function with concurrency control | ||||||
checkMarkdownFiles(docsFolderPath, validateDocs, '', 5); // Limit concurrency to 5 | ||||||
checkMarkdownFiles(blogsFolderPath, validateBlogs, '', 5); // Limit concurrency to 5 | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add 'p-limit' to the project's dependencies
The
p-limit
module is imported but not listed in your project's dependencies. Please add it to yourpackage.json
to ensure the module is available during runtime.🧰 Tools
🪛 eslint
[error] 4-4: 'p-limit' should be listed in the project's dependencies. Run 'npm i -S p-limit' to add it
(import/no-extraneous-dependencies)
[error] 4-4: Delete
·
(prettier/prettier)
🪛 GitHub Check: codecov/patch
[warning] 4-4: scripts/markdown/check-markdown.js#L4
Added line #L4 was not covered by tests
🛠️ Refactor suggestion
Increase test coverage for the new code
The new code added in these lines is not covered by tests, as indicated by Codecov. Please add tests to ensure the new concurrency control functionality is properly tested.
Also applies to: 104-105, 122-125, 128-132, 134-138, 141-141, 147-147, 151-151, 159-160
🧰 Tools
🪛 eslint
[error] 4-4: 'p-limit' should be listed in the project's dependencies. Run 'npm i -S p-limit' to add it
(import/no-extraneous-dependencies)
[error] 4-4: Delete
·
(prettier/prettier)
🪛 GitHub Check: codecov/patch
[warning] 4-4: scripts/markdown/check-markdown.js#L4
Added line #L4 was not covered by tests