Question

I have a thread which does a bit of processing in the background to make the controller more responsive, however, the test case fails to run. It appears to lock up printing 'EEEEEE' for about 5 minutes.

Here is my thread in the controller. exit doesn't seem to make a difference.

  Thread.new do # don't delay user response
    @post.fetchImage
    @post.save
    Thread.exit
  end

The thread has timeouts of 5s so it can't take 5-10m.

After 10m of waiting, it spits out errors:

  1) Error:
PostIntegrationTest#test_sweep_redistributes_balances_correctly:
ActiveRecord::ConnectionTimeoutError: could not obtain a database connection within 5.000 seconds (waited 5.002 seconds)
Était-ce utile?

La solution

Ok I solved it by using Fibers!

  f = Fiber.new do # don't delay user response
    @post.fetchImage
    @post.save
  end
  f.resume

Weird that Thread wouldn't work. Using Ruby 2.0.0.


Ok this is even stranger than I though! Fibers would block the response to the browser in the server!

  # Threads don't work in test, and Fibers are not asynchronous in the server!
  if Rails.env == 'test'
    f = Fiber.new do # don't delay user response
      @post.fetchImage
      @post.save
    end
    f.resume
  else 
    Thread.new do # don't delay user response
      @post.fetchImage
      @post.save
    end
  end

This doesn't seem right...


Ok I found a different way, which seems more right. I'm just surprised Rails doesn't check out a DB connection automatically for a thread and check it back in when the thread is finished all in the background.

    Thread.new do # don't delay user response
      ActiveRecord::Base.connection_pool.with_connection do # checkout/checkin DB connection
        @post.fetchImage
        @post.save
      end
      # ActiveRecord::Base.connection_pool.clear_stale_cached_connections! # Paranoid mode
    end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top