I have a JRuby application deployed on Google compute engine. I noticed that it takes a while to load the celluloid
gem. After looking into more details, I found that it is taking more time to load celluloid/internals/stack
.
Usually, it takes more than 2 mins. Once it even took around 41 mins to load that. The server has a good configuration with 15Gb RAM and 4 cores.
JAVA version
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)
JRUBY version
jruby 9.0.5.0 (2.2.3) 2016-01-26 7bee00d Java HotSpot(TM) 64-Bit Server VM 25.74-b02 on 1.8.0_74-b02 +jit [linux-amd64]
When I tried same with ruby it loads celluloid
quickly.
haveged
to replenish entropy faster on virtual machines.You probably don't have enough entropy to generate UUID
's pulled from SecureRandom
which under jRuby
runs out of randomness easily. Especially on virtual machines. So your virtual machine is literally waiting for more randomness to be possible. haveged
helps replenish that randomness lightening fast by collecting new kinds of entropy.
Download: http://www.issihosts.com/haveged/downloads.html
Under Debian-like Linux flavors like Mint and Ubuntu, this gets that done:
sudo apt-get install haveged
SecureRandom
under jRuby
...In the past I had this issue also, and had to use strace
to locate the issue. Notice this file, which is the one loaded just before the line you mentioned in your question ... internals/uuid.rb
:
require "securerandom"
module Celluloid
module Internals
# Clearly Ruby doesn't have enough UUID libraries
# This one aims to be fast and simple with good support for multiple threads
# If there's a better UUID library I can use with similar multithreaded
# performance, I certainly wouldn't mind using a gem for this!
module UUID
values = SecureRandom.hex(9).match(/(.{8})(.{4})(.{3})(.{3})/)
PREFIX = "#{values[1]}-#{values[2]}-4#{values[3]}-8#{values[4]}".freeze
#de ...
end
end
end
That was the offending code, because it generates a 9
hex-digit string which it can use as a prefix for UUID
codes... using SecureRandom
.
Then later, there are uses of that via the Celluloid::Internals::UUID.generate
method. But at load-time, the Celluloid::Internals::UUID
module performs operations which require SecureRandom
... which jRuby
has had trouble with: