I use gem Curb (also tried with httparty ) to execute many http requests, and this works well. But in one of my tasks ( rake ) (where I make 20k + requests) I have a memory problem (Rails "eats" more than 2 GB of RAM until there is no more free memory).
It seems that Rails "did not wait" for an answer and moved to another thread in the loop, the problem is that in this way a lot of objects are created that are not collected by the garbage collector (I think) and is causing a memory leak.
Is there any way to tell the rails to wait for an answer? (I tried with sleep , but was not a sustainable solution).
I have a pseudo code:
def the_start while start_date <= end_date do # ~ 140 loop a_method_that_do_sub_specifics_call end end def a_method_that_do_sub_specifics_call some_data.each do |r| # ~ 180 loop do_a_call #do something with models (update/create entries,...) end end def do_a_call # called ~ 25k times # with the gem Curb version req = Curl::Easy.new do |curl| curl.ssl_verify_peer = false curl.url = url curl.headers['Content-type'] = 'application/json' end req.perform # actual version, with httparty gem req = HTTParty.get("#{url}", :headers => {'Content-type' => 'application/json'}) end
Rails does not seem to wait for req.perform results.
EDIT:
I also tried to initialize the Curl::Easy object only once, using Curl::Easy.perform() and req.close (which should call GC implicitly) after the call, but without success when using a large amount of memory. The only solution that (I think) can work is to “block” the rails until an answer arrives, but how?
EDIT 2
In another task, I only call a_method_that_do_sub_specifics_call without any problems.
EDIT 3
After some performance modification (placing find_each(:batch_size => ...) , GC.start , ...) the task works a little better .. now the first cycle ~ 100 ( do_a_call ) do_a_call , after which the memory usage jump from 100 MB to 2 Gbps + again.
source share