r-lib / keyring

:closed_lock_with_key: Access the system credential store from R
https://keyring.r-lib.org/
Other
196 stars 28 forks source link

Error Cannot lock keyring in long parallel process #129

Closed djhocking closed 1 year ago

djhocking commented 2 years ago

I am running a bunch of parallel processes that use keyring to access database passwords and such. It generally works fine but after a couple hours, right near the end, I keep getting and error:

Error in { : task 2738 failed - "Cannot lock keyring file"

My process is something like:

ans <- foreach(i = longList,
                 .packages = c("DBI", "ROracle", "keyring", "data.table")
  ) %dopar% {

    keyring::keyring_unlock("apsd_ma", password = pw) # pass it the temporarily saved password
    con <- apsdFuns::roracle_login(key_name = 'xxxxx', key_service = 'yyyyy')
    # lots of stuff that takes a long time
    ROracle::dbDisconnect(con)
}

I never actually try to lock the keyring and I'm not sure if it would work since it's being used by many parallel processes, but I really don't fully understand how the parallel processes or keyring work internally. I am wondering if this is being processes are finished and waiting on other processes or if there is an internal lockout time for the keyring. Could it be related to the SEXP part in this:

https://github.com/r-lib/keyring/blob/f767946ec588191b88d4e609354843a10229d47c/src/keyring_secret_service.c

I am on RHEL 8.6 with R 4.2.1 on RStudio Server and keyring 1.3.0.

I have a hacky workaround but wanted to see if you had recommendations for a better way to handle this. Thanks!

gaborcsardi commented 2 years ago

Which keyring backend do you use?

djhocking commented 2 years ago

I'm not 100% sure how to check but I'm seeing these three

libsecret-0.18.6-1.el8.x86_64
libsodium-1.0.18-2.el8.x86_64 
libsodium-devel-1.0.18-2.el8.x86_64

installed on the server.

gaborcsardi commented 2 years ago

You can run keyring::default_backend() to see the default backend.

djhocking commented 2 years ago

Oh I tried that but think I missed it at the time because I didn't realize that 'file' was the actual backend. Thanks.

> keyring::default_backend()
<keyring backend: ‘file’>
Store secrets in encrypted files.
system
gaborcsardi commented 2 years ago

What keyring operations do your parallel processes use? Just unlock() and get()? Or do you also set keys?

djhocking commented 2 years ago

unlock(), get(), and as.character(keyring::key_list(key_service, key_name)$username). No setting of keys. I output fst files during the foreach process so I know it works for 1000s of iterations over a couple hours before failing.

gaborcsardi commented 2 years ago

There is a timeout for locking the keyring file, it defaults to 1s, which is usually enough, but if many processes want to read it at the same time, that might not be enough. You can increase it with an option:

options(keyring_file_lock_timeout = 100000)

It is in milliseconds, so this is 10s.

djhocking commented 2 years ago

Fantastic, thanks! I'll give it a try. I bet that's the issue.

gaborcsardi commented 2 years ago

Fingers crossed.