sprinkle-tool / sprinkle

Sprinkle is a software provisioning tool you can use to build remote servers with. eg. to install a Rails, or Sinatra stack on a brand new slice directly after its been created
https://github.com/sprinkle-tool/sprinkle
MIT License
1.15k stars 138 forks source link

Problems with File installer on OSX 10.8.3 with ruby 1.9.3p327 #144

Closed saleslash closed 11 years ago

saleslash commented 11 years ago

I'm using 0.7.3 version of the Sprinkle gem, and I am noticing a problem on my development machine.

So I have a couple of packages that run in order. The first one issues a runner statement to "git clone" a repository onto the remote machine. The second package then uploads a single configuration file into place within the newly cloned path.

File uploads work perfectly fine for me in other cases, except in this scenario. In the case that a File installer upload comes after a long running process, I get an error similar to this:

/Users/myuser/.rvm/gems/ruby-1.9.3-p327/gems/net-scp-1.1.2/lib/net/scp/upload.rb:117:in `stat': No such file or directory - /var/folders/38/qx6vpy0j06s6nz2l390mmvwr0000gp/T/github_deploy_site_config20130719-62929-hb8b9v (Errno::ENOENT)

After a couple of hours of scratching my head, I finally found the culprit and a temporary solution.

It seems the File installer makes use of the Tempfile class, copying the contents of the local file into a new temporary file, and then passing the path of the temporary file to the net-scp upload method.

When the process takes too long, Ruby's GC kicks in and clean's up the local temporary files before the File installer method can be called to upload the file. So the file goes missing and you get the error above.

If I add GC.disable and GC.enable around the deployment block, like shown below, then everything goes back to working, I can see when I do this that the temp files are not being cleaned up by the GC until after the script exits.

GC.disable deployment do delivery :ssh do user "root" role :app, "some.server.com" end end GC.enable

From what I understand based on a little research, it seems that the GC cleans up the files generated by Tempfile when they go out of scope and no more references exist for them. So far, I have only confirmed this on my OSX workstation running and RVM build of Ruby 1.9.3p327. I'm not sure if this Tempfile behavior is specific to the 1.9 version of ruby, to OSX, or if this is generally how it behaves.

I'm wondering if anyone else can reproduce this, and perhaps if someone with more experience with the Sprinkle codebase can look to see how it can be remedied.

Thanks for your time.

joshgoebel commented 11 years ago

Can you reproduce on master? I think this is fixed just not released yet.

Thanks, Josh

On Jul 19, 2013, at 9:09 PM, saleslash notifications@github.com wrote:

I'm using 0.7.3 version of the Sprinkle gem, and I am noticing a problem on my development machine.

So I have a couple of packages that run in order. The first one issues a runner statement to "git clone" a repository onto the remote machine. The second package then uploads a single configuration file into place within the newly cloned path.

File uploads work perfectly fine for me in other cases, except in this scenario. In the case that a File installer upload comes after a long running process, I get an error similar to this:

/Users/edvin/.rvm/gems/ruby-1.9.3-p327/gems/net-scp-1.1.2/lib/net/scp/upload.rb:117:in `stat': No such file or directory - /var/folders/38/qx6vpy0j06s6nz2l390mmvwr0000gp/T/github_deploy_site_config20130719-62929-hb8b9v (Errno::ENOENT)

After a couple of hours of scratching my head, I finally found the culprit and a temporary solution.

It seems the File installer makes use of the Tempfile class, copying the contents of the local file into a new temporary file, and then passing the path of the temporary file to the net-scp upload method.

When the process takes too long, Ruby's GC kicks in and clean's up the local temporary files before the File installer method can be called to upload the file. So the file goes missing and you get the error above.

If I add GC.disable and GC.enable around the deployment block, like shown below, then everything goes back to working, I can see when I do this that the temp files are not being cleaned up by the GC until after the script exits.

GC.disable deployment do delivery :ssh do user "root" role :app, "some.server.com" end end GC.enable

From what I understand based on a little research, it seems that the GC cleans up the files generated by Tempfile when they go out of scope and no more references exist for them. So far, I have only confirmed this on my OSX workstation running and RVM build of Ruby 1.9.3p327. I'm not sure if this Tempfile behavior is specific to the 1.9 version of ruby, to OSX, or if this is generally how it behaves.

I'm wondering if anyone else can reproduce this, and perhaps if someone with more experience with the Sprinkle codebase can look to see how it can be remedied.

Thanks for your time.

Regards,

Edvin

— Reply to this email directly or view it on GitHub.

saleslash commented 11 years ago

Josh,

Thanks for the quick reply. I should have explored a bit more before posting. I just saw that this was already reported and patched in master.

I set my Gemfile to pull directly from master, and sure enough, the problem has been fixed.

Thanks again, and sorry for the duplicate request.

joshgoebel commented 11 years ago

Pushing 0.7.4.