R/lockExternalDir.R

Defines functions unlockExternalDir lockExternalDir

Documented in lockExternalDir unlockExternalDir

#' Lock external directory 
#'
#' Lock the external Conda installation directory so that multiple processes cannot try to install at the same time.
#'
#' @param path String containing the path to the external directory.
#' @param ... For \code{lockExternalDir}, further arguments to pass to \code{\link{lockDirectory}} such as \code{exclusive}.
#' For \code{unlockExternalDir}, further arguments to pass to \code{\link{unlockDirectory}} such as \code{clear}.
#' @param lock.info A lock object generated by \code{\link{lockDirectory}}.
#'
#' @return 
#' \code{lockExternalDir} will return a lock object from \code{\link{lockDirectory}}.
#' 
#' \code{unlockExternalDir} will unlock the file and return \code{NULL} invisibly.
#'
#' @details
#' This will apply a lock to the (possibly user-specified) external Conda installation directory,
#' so that a user trying to run parallel \pkg{basilisk} processes will not have race conditions during lazy Conda installation.
#' We use \pkg{dir.expiry} to manage the locking process for us, with the following strategy:
#' \itemize{
#' \item If a system installation is being performed, we do not perform any locking.
#' Rather, the R package manager will lock the entire R installation directory for us.
#' \item If the external directory is not yet present, we establish an exclusive lock.
#' We then proceed to the creation of said directory and installation of Conda.
#' \item If an external installation directory is already present, we establish a shared lock.
#' This will wait for any exclusive lock to expire (and thus any currently running installation to finish).
#' No waiting is required if there are no existing exclusive locks.
#' }
#'
#' Note that locking is only required during installation of Conda (or its environments), not during actual use.
#' Once an installation/environment is created, we assume that it is read-only for all processes.
#' Technically, this might not be true if one were to install a new version of \pkg{basilisk} halfway through an R session,
#' which would prompt \code{\link{installConda}} to wipe out the old Conda installations;
#' but one cannot in general guarantee the behavior of running R sessions when package versions change anyway,
#' so we won't bother to protect against that.
#'
#' @author Aaron Lun
#'
#' @seealso
#' \code{\link{installConda}}, for an example of how to implement this locking approach.
#'
#' @examples
#' loc <- lockExternalDir()
#' unlockExternalDir(loc)
#'
#' @export
#' @importFrom dir.expiry lockDirectory
lockExternalDir <- function(path=getExternalDir(), ...) {
    lockDirectory(path, ...)
}

#' @export
#' @rdname lockExternalDir
#' @importFrom dir.expiry unlockDirectory
unlockExternalDir <- function(lock.info, ...) {
    if (!is.null(lock.info)) {
        unlockDirectory(lock.info, ...)
    }
    invisible(NULL)
}
LTLA/basilisk.utils documentation built on April 13, 2024, 1:14 a.m.