Hanging MySQL2 connections spun up in EventMachine - mysql

I'm running this code from the mysql2 gem docs:
require 'mysql2/em'
EM.run do
client1 = Mysql2::EM::Client.new
defer1 = client1.query "SELECT sleep(3) as first_query"
defer1.callback do |result|
puts "Result: #{result.to_a.inspect}"
end
client2 = Mysql2::EM::Client.new
defer2 = client2.query "SELECT sleep(1) second_query"
defer2.callback do |result|
puts "Result: #{result.to_a.inspect}"
end
end
It runs fine, printing the results
Result: [{"second_query"=>0}]
Result: [{"first_query"=>0}]
but then the script just hangs and never returns to the command line. Any idea what is going on?

EM.run will start an EventMachine reactor. That reactor just loops and loops and loops until you somehow tell it to stop. You can manually stop it using EM.stop.
In your case, you might want to check for the callback results and stop the reactor when both callbacks fired. Ilya's em-http-request library provides a nice interface for exactly that use case. Might be worth a look.

Related

Sinatra executing ls on sever side

I am trying to show in Chrome using Sinatra, the result of ls. But the explorer gets in an "Connecting..." loop.
My code is:
require 'rubygems' if RUBY_VERSION < "1.9"
require 'sinatra/base'
#This is the webservice to launch the gamma project
#Using Request at the principal webpage
class MyApp < Sinatra::Base
get '/' do
result = exec "ls"
puts result
end
end
I am not sure of that puts, I think that maybe is not the apropiate method. What could be happening and how can I solve it?
PS: In the explorer I used localhost.com:4567/
Use the backticks ( ` ) instead of the Kernel#exec command. The former returns a string that you can then use in your ruby process. The latter throws your execution context into a new process and has no return value.
get '/' do
result = %x`ls`
puts result
end
Note that the call to puts will not look very nice and that you'll probably want to format it or parse/manipulate it further. But at least you'll get something you can use.
As #pgblu pointed out you should use backticks.
https://stackoverflow.com/a/18623297/1279355
And the second thing, puts print the result only to your shell/log,
but to see the result in your chrome you need either:
get '/' do
result = %x`ls`
return result
end
or
get '/' do
result = %x`ls`
result
end
As you can see the return is optional, if there is no return Sinatra just displays the last variable/operation.

Why won't these threaded ActiveRecord queries run concurrently?

I'm experimenting to understand a problem in production, so I've thrown this snippet inside a controller action in dev to test:
start = Time.now
num_threads = 6
results = Queue.new
saved_results = []
threads = []
connections = []
semaphore = Mutex.new
# start threads
(1..num_threads).each do |i|
threads << Thread.new do
#semaphore.synchronize { connections << ActiveRecord::Base.connection } # for cleanup?
#ActiveRecord::Base.connection.execute("select sleep(1.6);") # runs sequentially
sleep(1.6) # runs concurrently
result = User.find_by_id(i)
results << [i, result]
end
end
# end option 1 - let everyone finish
threads.each(&:join)
# end option 2 - simulate early exit condition
#while saved_results.count < 3 do saved_results << results.pop end
#threads.each(&:exit)
# cleanup/close open connections?
#connections.select(&:active?).each(&:disconnect!)
elapsed = Time.now - start
render :text => [ elapsed.to_s, saved_results.size, results.size ].join(", ")
sleep(1.6) executes in approximately 1.6 seconds, as expected.
However, the ActiveRecord select sleep(1.6); takes 6 * 1.6 = 9.6 seconds, despite mysql console show processlist; displaying that independent connections are opened for each thread*.
What's going on? Why won't the ActiveRecord queries run concurrently? I've also experienced this in production console.
I do have config.threadsafe! set in config/environment.rb. If it matters, I'm using Rails 2.3.
*These connections have to be manually closed? Production always has a lot of open connections that are doing nothing, causing Mysql::Error: Too many connections. I'll probably submit this issue as a another question.
Some remarks:
rails 2.3 itself is afaik itself not really threadsafe, since rails 3.x it is. But for this case that does not really matter I think.
you should be using ruby 1.9 at least. The "green threads" in 1.8 are less than optimal. While treading in ruby 1.9 still is not optimal, it is better. For real threading you should check out jruby or rubinius (no GIL).
you should be using the mysql2 gem. The mysql gem keeps the GIL while waiting for a response from the database.

Get value of java options in jruby

I'd like to know, in a running jruby script, which java options are set. Is there a way to do this?
My problem is this: There are some scripts that I know require much more memory than others, and I would like to add a constraint in the code so that execution will stop early with proper warnings, rather than running out of memory at some unspecified time in the future.
Perhaps something I could stick in a BEGIN{}, like:
if is_set_joption?('-J-Xmx') then
if get_joption('-J-Xmx').match(/\d+/)[0].to_i < 1000 then
puts "You're gonna run out of memory...";
abort();
end
else
puts "I recommend you start with -J-Xmx1000m.";
abort();
end
(... where is_set_joption? and get_joption are made up methods.)
Running jruby 1.7.8.
It'll be in your ENV if you've set JAVA_OPTS in your environment. You could get it from that.. You've already initiated the JVM at this point though, so you'll want to set that elsewhere, like in your command line when you exec jruby with -D
One can do:
require 'java';
java_import 'java.lang.Runtime';
mxm = Runtime.getRuntime.maxMemory.to_i;
if mxm < (512 * 1024 * 1024) then
raise "You're gonna need a bigger boat.";
end

Why is my object.save working in one place and failing in another?

Could someone tell me why this works:
require 'rubygems'
require 'mysql2'
#inverters=Inverter.where(:mac=>#mac)
Inverter.transaction do
#inverters.each do |inverter|
inverter.ip = #client_ip
inverter.save # Object is saved:)!
end
end
But this does not?:
require 'rubygems'
require 'mysql2'
#outputs=<a two dimensional hash>
Output.transaction do
#outputs.each do |out|
#newOut = Output.new
#newOut.inverter_id = out[:inverter_id]
#newOut.eac = out[:eac]
#newOut.pac = out[:pac]
#newOut.vac = out[:vac]
#newOut.iac = out[:iac]
#newOut.epv = out[:epv]
#newOut.ppv = out[:ppv]
#newOut.vpv = out[:vpv]
#newOut.save # Object fails to save to db:(.
# 2 lines of other code
end
end
Both objects save successfully when I enter the same commands manually in the rails console, but the second one fails within my script. I have done extensive debugging making sure that all variables ('out' and '#outputs') have expected values and again it is all working in the console. I am using Ruby 1.8.7, Rails 3.0.3 and mysql2 gem version 0.2.7. Thank you so much in advance!
The first thing I did to figure this out was to open up a separate tab in terminal, navigate to my rails app folder and follow what was going on with mySQL behind the scenes by typing the following line: tail -f log/development.log. I could see on running the second not working script above, in the log that after the INSERT into outputs table line, it would just say 'ROLLBACK'. The reason this was happening was that I had two lines of random code after my #newOut.save statement. When I took those two lines out of the transaction loop, everything worked. This is clearly a total newbie error, but I hope it helps someone.

Ruby Shoes and MySQL: GUI freezes, should I use threads?

I'm trying to learn Shoes and decided to make a simple GUI to run a SQL-script line-by-line.
My problem is that in GUI pressing the button, which executes my function, freezes the GUI for the time it takes the function to execute the script.
With long scripts this might take several minutes.
Someone had a similar problem (http://www.stackoverflow.com/questions/958662/shoes-and-heavy-operation-in-separate-thread) and the suggestion was just to put intensive stuff under a Thread: if I copy the math-code from previously mentioned thread and replace my mysql-code the GUI works without freezing, so that probably hints to a problem with how I'm using the mysql-adapter?
Below is a simplified version of the code:
problem.rb:
# copy the mysql-gem if not in gem-folder already
Shoes.setup do
gem 'mysql'
end
require "mysql"
# the function that does the mysql stuff
def someFunction
con = Mysql::real_connect("myserver", "user", "pass", "db")
scriptFile = File.open("myfile.sql", "r")
script = scriptFile.read
scriptFile.close
result = []
script.each_line do |line|
result << con.query(line)
end
return result
end
# the Shoes app with the Thread
Shoes.app do
stack do
button "Execute someFunction" do
Thread.start do
result = someFunction
para "Done!"
end
end
end
stack do
button "Can't click me when GUI is frozen" do
alert "GUI wasn't frozen?"
end
end
end
I think the problem arises from scheduling which is done by ruby, not by the operating system. Probably just a special case with shoes + mysql.
As a workaround i'd suggest you spawn a separate process for the script and use socket or file based communication between the processes.