fix: builds should no accumulate on repeated changes (closes #404)

This commit is contained in:
Jacky Zhao 2023-08-23 11:36:34 -07:00
parent a25bc8a5e4
commit 107c8d413a
2 changed files with 47 additions and 47 deletions

View File

@ -393,10 +393,16 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started.
}) })
const buildMutex = new Mutex() const buildMutex = new Mutex()
const timeoutIds = new Set() let lastBuildMs = 0
let cleanupBuild = null let cleanupBuild = null
const build = async (clientRefresh) => { const build = async (clientRefresh) => {
const buildStart = new Date().getTime()
lastBuildMs = buildStart
const release = await buildMutex.acquire() const release = await buildMutex.acquire()
if (lastBuildMs > buildStart) {
release()
return
}
if (cleanupBuild) { if (cleanupBuild) {
await cleanupBuild() await cleanupBuild()
@ -428,12 +434,6 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started.
clientRefresh() clientRefresh()
} }
const rebuild = (clientRefresh) => {
timeoutIds.forEach((id) => clearTimeout(id))
timeoutIds.clear()
timeoutIds.add(setTimeout(() => build(clientRefresh), 250))
}
if (argv.serve) { if (argv.serve) {
const connections = [] const connections = []
const clientRefresh = () => connections.forEach((conn) => conn.send("rebuild")) const clientRefresh = () => connections.forEach((conn) => conn.send("rebuild"))
@ -539,7 +539,7 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started.
ignoreInitial: true, ignoreInitial: true,
}) })
.on("all", async () => { .on("all", async () => {
rebuild(clientRefresh) build(clientRefresh)
}) })
} else { } else {
await build(() => {}) await build(() => {})

View File

@ -81,7 +81,7 @@ async function startServing(
} }
const initialSlugs = ctx.allSlugs const initialSlugs = ctx.allSlugs
const timeoutIds: Set<ReturnType<typeof setTimeout>> = new Set() let lastBuildMs = 0
const toRebuild: Set<FilePath> = new Set() const toRebuild: Set<FilePath> = new Set()
const toRemove: Set<FilePath> = new Set() const toRemove: Set<FilePath> = new Set()
const trackedAssets: Set<FilePath> = new Set() const trackedAssets: Set<FilePath> = new Set()
@ -111,11 +111,14 @@ async function startServing(
} }
// debounce rebuilds every 250ms // debounce rebuilds every 250ms
timeoutIds.add(
setTimeout(async () => { const buildStart = new Date().getTime()
lastBuildMs = buildStart
const release = await mut.acquire() const release = await mut.acquire()
timeoutIds.forEach((id) => clearTimeout(id)) if (lastBuildMs > buildStart) {
timeoutIds.clear() release()
return
}
const perf = new PerfTimer() const perf = new PerfTimer()
console.log(chalk.yellow("Detected change, rebuilding...")) console.log(chalk.yellow("Detected change, rebuilding..."))
@ -137,11 +140,11 @@ async function startServing(
contentMap.delete(fp) contentMap.delete(fp)
} }
const parsedFiles = [...contentMap.values()]
const filteredContent = filterContent(ctx, parsedFiles)
// TODO: we can probably traverse the link graph to figure out what's safe to delete here // TODO: we can probably traverse the link graph to figure out what's safe to delete here
// instead of just deleting everything // instead of just deleting everything
await rimraf(argv.output) await rimraf(argv.output)
const parsedFiles = [...contentMap.values()]
const filteredContent = filterContent(ctx, parsedFiles)
await emitContent(ctx, filteredContent) await emitContent(ctx, filteredContent)
console.log(chalk.green(`Done rebuilding in ${perf.timeSince()}`)) console.log(chalk.green(`Done rebuilding in ${perf.timeSince()}`))
} catch { } catch {
@ -152,8 +155,6 @@ async function startServing(
toRebuild.clear() toRebuild.clear()
toRemove.clear() toRemove.clear()
release() release()
}, 250),
)
} }
const watcher = chokidar.watch(".", { const watcher = chokidar.watch(".", {
@ -168,7 +169,6 @@ async function startServing(
.on("unlink", (fp) => rebuild(fp, "delete")) .on("unlink", (fp) => rebuild(fp, "delete"))
return async () => { return async () => {
timeoutIds.forEach((id) => clearTimeout(id))
await watcher.close() await watcher.close()
} }
} }