Skip to content
Snippets Groups Projects
Commit a40ca4d6 authored by Florian Angerer's avatar Florian Angerer
Browse files

Add file-based locking mechanism for package cache.

parent 61c08214
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,31 @@
# questions.
#
lock.file.name <- ".lock"
pkg.cache.max.retries <- 3L
pkg.cache.lock <- function(version.dir) {
tries <- 0L
version.lock.file <- file.path(version.dir, lock.file.name)
while (file.exists(version.lock.file)) {
# wait for 1 second
Sys.sleep(1)
tries <- tries + 1L
if (tries >= pkg.cache.max.retries) {
return (FALSE)
}
}
log.message("CREATING LOCK FILE", version.lock.file)
tryCatch(file.create(version.lock.file), error=function(e) return (FALSE), warning=function(e) return (FALSE))
}
pkg.cache.unlock <- function(version.dir) {
version.lock.file <- file.path(version.dir, lock.file.name)
tryCatch(file.remove(version.lock.file))
}
is.fastr <- function() {
length(grep('FastR', R.Version()$version.string))
}
......@@ -36,8 +61,6 @@ log.message <- if(!exists("log.message")) {
log.message
}
pkg.cache.install <- function(pkg.cache.env, pkgname, pkg.version, lib.install, install.cmd) {
pkg <- list(Package=pkgname, Version=pkg.version)
is.cached <- pkg.cache.get(pkg.cache.env, pkg, lib.install)
......@@ -61,6 +84,12 @@ pkg.cache.get <- function(pkg.cache.env, pkg, lib) {
return (FALSE)
}
# lock version directory
if (!pkg.cache.lock(version.dir)) {
log.message("could not lock version dir ", version.dir, level=1)
return (FALSE)
}
pkgname <- as.character(pkg["Package"])
pkg.version <- as.character(pkg["Version"])
......@@ -82,7 +111,7 @@ pkg.cache.get <- function(pkg.cache.env, pkg, lib) {
}, error = function(e) {
log.message("could not extract cached package from ", fromPath , " to ", toPath, level=1)
return (FALSE)
})
}, finally = pkg.cache.unlock(version.dir) )
}
log.message("cache miss for package ", pkgname, level=1)
......@@ -102,6 +131,16 @@ pkg.cache.insert <- function(pkg.cache.env, pkg, lib) {
dir.create(version.dir)
}
# lock version directory
if (!pkg.cache.lock(version.dir)) {
log.message("could not insert: version dir ", version.dir, " is locked", level=1)
return (FALSE)
}
}, error = function(e) {
log.message("could not insert package '", pkgname, "' because: ", e$message)
})
tryCatch({
pkgname <- as.character(pkg["Package"])
pkg.version <- as.character(pkg["Version"])
fromPath <- file.path(lib, pkgname)
......@@ -133,7 +172,7 @@ pkg.cache.insert <- function(pkg.cache.env, pkg, lib) {
return (TRUE)
}, error = function(e) {
log.message("could not insert package '", pkgname, "' because: ", e$message)
})
}, finally = pkg.cache.unlock(version.dir) )
FALSE
}
......@@ -272,7 +311,13 @@ pkg.cache.get.version <- function(cache.dir, cache.version, table.file.name, cac
}
if (!is.null(updated.version.table)) {
version.subdir <- as.character(updated.version.table[updated.version.table$version == cache.version, "dir"])
write.csv(updated.version.table, version.table.name, row.names=FALSE)
if (!pkg.cache.lock(cache.dir)) {
return (NULL)
}
try({
write.csv(updated.version.table, version.table.name, row.names=FALSE)
}, finally=pkg.cache.unlock(cache.dir))
}
# return the version directory
......@@ -376,7 +421,6 @@ pkg.cache.internal.install <- function(pkg.cache.env, pkgname, contriburl, lib.i
pkg.list <- as.data.frame(available.packages(contriburl=contriburl), stringAsFactors=FALSE)
# query version of the package
#pkg.version <- as.character(pkg.list[pkg.list$Package == pkgname, "Version"])
pkg <- pkg.list[pkgname, c("Package", "Version")]
# compute transitive dependencies of the package to install
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment