mirror of
https://github.com/pesde-pkg/tooling.git
synced 2025-03-04 02:51:47 +00:00
feat(lib): use structured lock file with metadata
This allows for us to know whether a lock file is too old and hence invalid, and perform a sanity check to ensure that the resource it is meant to be protecting is the resource we are trying to access.
This commit is contained in:
parent
57605e87b8
commit
aef778883e
1 changed files with 27 additions and 17 deletions
|
@ -178,26 +178,32 @@ function installTool(tool: ToolId, installPath: pathfs.Path): number
|
|||
pathfs.writeDir(toolDir)
|
||||
end
|
||||
|
||||
type InstallLock = {
|
||||
expiration: number,
|
||||
resource: string,
|
||||
}
|
||||
|
||||
-- Attempt to read an existing lock in EAFP fashion
|
||||
local installLockFile = toolDir:join("LOCK")
|
||||
local isLocked, existingInstallPath = pcall(pathfs.readFile, installLockFile)
|
||||
local isLocked, lockFileContents = pcall(pathfs.readFile, installLockFile)
|
||||
if isLocked then
|
||||
-- If the lock was held and we know the same tool that we are trying to install
|
||||
-- is also being installed elsewhere, we wait for that installation attempt to
|
||||
-- finish, i.e., the lock file is removed, and then run the freshly installed tool
|
||||
if installPath:toString() == existingInstallPath then
|
||||
-- Disable the progress bar since we're not actually an installation process
|
||||
_G.interactive = false
|
||||
bar:stop()
|
||||
|
||||
warn("Waiting for existing installation process for tool to exit")
|
||||
local lockFile: InstallLock = serde.decode("json", lockFileContents)
|
||||
assert(lockFile.resource == installPath:toString(), "Mistmatch between lock and expected resource")
|
||||
|
||||
local lockWatchStart = os.clock()
|
||||
warn("Waiting for existing installation process for tool to exit")
|
||||
while pathfs.isFile(installLockFile) do
|
||||
if os.clock() - lockWatchStart > 30_000 then
|
||||
if os.time() > lockFile.expiration then
|
||||
-- If more than 30s has passed since we started waiting for the lock
|
||||
-- to be released, we assume something went wrong and error
|
||||
error("Installation lock was held for too long (>30s)")
|
||||
-- to be released, we assume something went wrong and error; this should
|
||||
-- also remove the lock for subsequent runs
|
||||
error("Installation lock was held for too long (>60s)")
|
||||
end
|
||||
|
||||
task.wait(1)
|
||||
|
@ -205,10 +211,14 @@ function installTool(tool: ToolId, installPath: pathfs.Path): number
|
|||
|
||||
return runTool(installPath)
|
||||
end
|
||||
end
|
||||
|
||||
-- Write a lock file to prevent concurrent installation attempts
|
||||
pathfs.writeFile(installLockFile, installPath:toString())
|
||||
local lockFile: InstallLock = {
|
||||
resource = installPath:toString(),
|
||||
expiration = os.time() + 60_000, -- lock expires in 60s from time of issue
|
||||
}
|
||||
|
||||
pathfs.writeFile(installLockFile, serde.encode("json", lockFile))
|
||||
|
||||
local toolAlias = toolAliasOrDefault(tool)
|
||||
local client = Github.new(
|
||||
|
|
Loading…
Add table
Reference in a new issue