Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenSSL causing very slow Rails boot time on Windows

I'm having a problem with Ruby on Rails running extremely slowly. I'm using Ruby 2.1.3p242 and Rails 4.2.1 on a Windows 8 machine.

Whenever I run anything that requires rails to boot (including tests) it takes a long time to get up and running. I put some calls to Benchmark in config/environment.rb on a clean install of rails:

require File.expand_path('../application', __FILE__)
User cpu    System Cpu   Total Cpu   elapsed time
0.000000    0.000000     0.000000    (0.000000)

Rails.application.initialize!
15.282000   2.891000  18.173000 ( 18.201173)

Clearly Rails.application.initialize is taking an absurdly long time considering its a clean install.

Thanks in advance for your help

Edit-1: I'm running on a dual core i3 [email protected] with 4gb of RAM. I don't think my machine is too bad as it runs most things very well.

Edit-2: I ran ruby-prof on Rails.application.initialize and found the culprit. A process was taking up 85% of the run time:

<Module::SecureRandom>#random_bytes
<Module::OpenSSL::Random>#random_bytes

This is apparently occuring in Ruby21/lib/ruby/2.1.0/securerandom.rb#62 I looked up line 62 in that file and this is what I found:

return OpenSSL::Random.random_bytes(n)

So anyone have any idea what this means?

like image 232
Circuit 8 Avatar asked May 01 '15 09:05

Circuit 8


2 Answers

Edit-2: I ran ruby-prof on Rails.application.initialize and found the culprit. A process was taking up 85% of the run time:

<Module::SecureRandom>#random_bytes
<Module::OpenSSL::Random>#random_bytes

Yeah, the OpenSSL code for seeding the random number generator is problematic on Windows. See Random Numbers and Windows Issues on the OpenSSL wiki.


return OpenSSL::Random.random_bytes(n)

So anyone have any idea what this means?

Ruby is returning random numbers. In this case, OpenSSL will autoseed itself before retuning random number with RAND_poll since no other seed was provided.


Ruby should not call RAND_poll or allow it to be implicitly called by the library. If the random number generator has not been seeded, then the library will automatically seed itself by calling RAND_poll internally.

Rather, Ruby should read bytes from the OS using CryptGenRandom, and then call OpenSSL's RAND_seed. That will avoid the call to RAND_poll.

like image 175
jww Avatar answered Oct 05 '22 09:10

jww


Putting this in my config/application.rb (before require 'rails/all') speeds up rails s by 10-15 seconds on windows.

require 'securerandom'
SecureRandom.hex(16)
like image 42
Ben Taitelbaum Avatar answered Oct 05 '22 11:10

Ben Taitelbaum