Closed jacobvosmaer closed 10 years ago
Yep, definitely worth calling out here. Merging.
I wanted to jot down some notes here after digging around a bit.
The :chdir
implementation takes place entirely outside of the system level posix_spawn
invocations, which don't support modifying the working directory of the spawned process that I can tell. Relevant parts of the posix-spawn codebase are here:
I'm curious how Ruby's built in Process::spawn
compares here. If it's made thread-safe somehow, it'd be interesting to see if we could accomplish the same.
I also verified that omitting the :chdir
option causes all working directory modification logic to be bypassed in the posix_spawn and Ruby fork/exec implementation.
@jacobvosmaer I'd also be interested to hear about your experience using posix-spawn in a threaded environment in general. GitHub makes heavy use of posix-spawn in a variety of production systems but I can't think of a single one that uses Ruby threads for anything beyond very trivial monitor type situation. Perhaps this should be called out even more heavily in the README.
@rtomayko GitLab runs all its background jobs in Sidekiq. I am not aware of any issues caused by the posix-spawn gem. Thanks for creating and maintaining it!
We don't use posix-spawn's chdir
much if at all; we considered using it more but after discovering the issue mentioned in this PR we decided not to.
About the Ruby Process::spawn implementation: I find the implementation a little hard to read with all the ifdefs going on, but I would expect them to do the equivalent of 'fork { chdir; exec }'.
Process::spawn indeed runs chdir
between fork
and exec
. There's a catch-all function rb_execarg_run_options
here that deals with the stuff between fork
and exec
: chdir, uid, gid, fds, and so forth.
Great, thanks. I'm cool with leaving the README as is.
Not knowing exactly what posix_spawn(2) does and does not do for you, I was a little surprised when I found out that the posix-spawn gem changes the working directory of the calling process. This commit is an attempt to share what I have learned.