I'm developing a site using Middleman, apparently it is somehow threaded. Whenever multiple JavaScript is run in the same time using different threads, Ruby process freezes, cannot be interrupted, and must be kill -9ed.
Test Code
# deadlock_test.rb
require 'execjs'
# The following code is used to test this bug.
# It does heavy computation stuff (pauses for 0.5 seconds) and returns "ok".
code = %q((function() {
var s = new Date().getTime() + 500
while (new Date().getTime() < s) {
}
return "ok"
})())
run = proc do
ExecJS.eval(code)
end
puts "The expected result is [ \"ok\", \"ok\" ]"
puts
puts "Running sequentially without threads (should take 1 second)"
p [run.call, run.call]
puts
puts "Running concurrently using threads (should take 0.5 seconds)"
p [Thread.new(&run), Thread.new(&run)].map(&:value)
Expected Result
▹ ruby deadlock_test.rb
The expected result is [ "ok", "ok" ]
Running sequentially without threads (should take 1 second)
["ok", "ok"]
Running concurrently using threads (should take 0.5 seconds)
["ok", "ok"]
Actual Result
▹ ruby deadlock_test.rb
The expected result is [ "ok", "ok" ]
Running sequentially without threads (should take 1 second)
["ok", "ok"]
Running concurrently using threads (should take 0.5 seconds)
^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^Z
[1] + 41277 suspended ruby deadlock_test.rb
▹ kill %1
▹ kill %1
▹ kill %1
▹ kill %1
▹ kill -9 %1
[1] + 41277 killed ruby deadlock_test.rb
Workaround
Use Node runtime with ExecJS instead: EXECJS_RUNTIME=Node
Related Issues
middleman/middleman#1367
Discussion
Is it a good idea for ExecJS to default to NodeJS on platforms where this is affected until the problem with therubyracer is fixed?
Environment
Background
I'm developing a site using Middleman, apparently it is somehow threaded. Whenever multiple JavaScript is run in the same time using different threads, Ruby process freezes, cannot be interrupted, and must be
kill -9
ed.Test Code
Expected Result
Actual Result
Workaround
Use Node runtime with ExecJS instead:
EXECJS_RUNTIME=Node
Related Issues
Discussion