Hello,
I’m writing a server with EM. I’m having some long-running tasks, so I’m
deferring those requests using EM.defer.
However, after 5 such deferred requests AR suddently stops working…
I’m using AR 2.3.4, so concurrency shouldn’t be a problem. Gems
configuration:
REQUIRED_GEMS = [
[‘mysql’, ‘>=2.7.0’],
[‘activerecord’, ‘=2.3.4’],
[‘activesupport’, ‘=2.3.4’],
[‘eventmachine’, ‘=0.12.6’],
[‘json’, ‘>=1.1.6’],
“daemons”
]
Anyway, as you can see it happens after 5 requests (just simulated
action, one select query):
[2009-09-09 23:32:35|main|info ] Starting server…
[2009-09-09 23:32:36|main|info ] [Resources manager]
[Resources manager END] Time taken: 0.031 seconds
[2009-09-09 23:32:37|main|info ] [Resources manager]
[Resources manager END] Time taken: 0.016 seconds
[2009-09-09 23:32:38|main|info ] [Resources manager]
[Resources manager END] Time taken: 0.000 seconds
[2009-09-09 23:32:39|main|info ] [Resources manager]
[Resources manager END] Time taken: 0.016 seconds
[2009-09-09 23:32:40|main|info ] [Resources manager]
[Resources manager END] Time taken: 0.000 seconds
[2009-09-09 23:32:41|main|info ] [Resources manager]
[Resources manager END with EXCEPTION]
#<ActiveRecord::ConnectionTimeoutError: c
ould not obtain a database connection within 5 seconds. The max pool
size is cu
rrently 5; consider increasing it.>
I’m running this code:
EventMachine::run {
EventMachine::start_server “0.0.0.0”, 843, FlashPolicyServer
EventMachine::start_server “0.0.0.0”, CONFIG[‘port’], GameServer
Resources manager
EventMachine::PeriodicTimer.new(CONFIG[‘resources_manager.period’]) do
SingletonBlock.run(“Resources manager”, nil, nil, :defer => true) do
“Time taken: %4.3f seconds” % Benchmark.realtime {
ResourcesEntry.tick }
end
end
}
Where SingletonBlock is:
Class for running one block of same name at a time
class SingletonBlock
@@running = {}
@@lock = Mutex.new
class << self
def run(name, operation=nil, callback=nil, options={}, &block)
unless running?(name)
operation ||= block
options.reverse_merge!(:defer => true)
if options[:defer]
EventMachine.defer(
proc do
SingletonBlock.started(name)
LOGGER.block(name) { operation.call }
end,
proc do
LOGGER.block("#{name} CALLBACK") { callback.call } if
callback
SingletonBlock.finished(name)
end
)
else
SingletonBlock.started(name)
LOGGER.block(name) { operation.call }
LOGGER.block("#{name} CALLBACK") { callback.call } if callback
SingletonBlock.finished(name)
end
end
end
def running?(name)
@@lock.synchronize do
! @@running[name].nil?
end
end
def started(name)
@@lock.synchronize do
@@running[name] = true
end
end
def finished(name)
@@lock.synchronize do
@@running.delete(name)
end
end
end
end
If I don’t use EM.defer - everything works fine.
Googled - nothing found. Any ideas?