Skip to content
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

Parallel + DB Locking Issue #322

Closed
happyshows opened this issue Dec 20, 2017 · 4 comments
Closed

Parallel + DB Locking Issue #322

happyshows opened this issue Dec 20, 2017 · 4 comments

Comments

@happyshows
Copy link

Hi,

I have a regular batch job to save articrafts to local repo. And I was using mcparallel to do it.

library(parallel)
jobs <- lapply(files, function(f){
  mcparallel({
    res <- prepData(f)
    asave(res,'localRepo',artifactName = f,archiveMiniature = F,archiveSessionInfo = F,silent = T) %>% invisible()
  }, name = f)
})
mccollect(jobs)

However, one of the task failed which shows:

[1] "Error in rsqlite_send_query(conn@ptr, statement) : database is locked\n"
attr(,"class")
[1] "try-error"
attr(,"condition")
<Rcpp::exception in rsqlite_send_query(conn@ptr, statement): database is locked>

What type of parallel process should I use to avoid DB locking issue?

@pbiecek
Copy link
Owner

pbiecek commented Dec 31, 2017

Very interesting use-case.
By default, we are using SQLite database which is a very simple database linked with a single file.
The file is locked when new objects are added. It may cause errors when two or more processes are trying to connect to a LOCKed file.

I do not see how this can be solved for SQLite. The best solution is to use a more advanced database, like postgress. Try createPostgresRepo() and setPostgresRepo(). Postgress will handle concurrent access to a single database.

@jakubkuzilek
Copy link

jakubkuzilek commented Dec 31, 2017

Hi, I was dealing with the similar issue and my solution was to create save_to_repo_extended using package flock, which creates mutex to deal with critical code part:

save_to_repo_extended <- function(artifact,
                                  repoDir = archivist::aoptions("repoDir"),
                                  archiveData = TRUE,
                                  archiveTags = TRUE,
                                  archiveMiniature = TRUE,
                                  archiveSessionInfo = TRUE,
                                  force = TRUE, value = FALSE,
                                  ...,
                                  userTags = c(),
                                  silent = archivist::aoptions("silent"),
                                  ascii = FALSE,
                                  artifactName = deparse(substitute(artifact)),
                                  file_lock = NULL){ # passing the file lock
  if(is.null(file_lock)){ # if lock does not exists continue as usual
    return_value <- archivist::saveToRepo(artifact, repoDir, archiveData, archiveTags,
                                          archiveMiniature, archiveSessionInfo, force,
                                          value, ..., userTags, silent, ascii, artifactName)
  } else { # lock exists -> lock section and continue
    locker <- flock::lock(file_lock) # lock critical section
    return_value <- archivist::saveToRepo(artifact, repoDir, archiveData, archiveTags,
                                          archiveMiniature, archiveSessionInfo, force,
                                          value, ..., userTags, silent, ascii, artifactName)
    flock::unlock(locker) # unlock section
  }

  return_value
}

@happyshows
Copy link
Author

thanks, will try later.

pbiecek added a commit that referenced this issue Feb 19, 2018
@pbiecek
Copy link
Owner

pbiecek commented Feb 19, 2018

Thank you guys for this interesting use case.
In the version 2.3 I've added support of flock package to the saveToRepo function through use_flock parameter
http://pbiecek.github.io/archivist/reference/saveToRepo.html

@pbiecek pbiecek closed this as completed Feb 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants