without_sticking failing as MakaraMysql2Adapter disappears?
We started using the without_sticking feature of Makara, and noticed that after a short period of application up-time, the without_sticking would intermittently stop working. It appears, that it's switching away from the ActiveRecord::ConnectionAdapters::MakaraMysql2Adapter to ActiveRecord::ConnectionAdapters::Mysql2Adapter when the error is raised. What does not make sense is we attempted to shield the application from that potential problem by doing a check on the adapter before we call without_sticking.
Message NoMethodError: undefined method `without_sticking' for #ActiveRecord::ConnectionAdapters::Mysql2Adapter:0x007f4871605048
we called into Makara like:
Project::WithoutSticking.execute do
foo_bar
end
we have a library where we call:
module Project
module WithoutSticking
def self.execute
# If we are dealing with makara hit the slave properly
if ActiveRecord::Base.connection.instance_values["config"][:adapter] == "mysql2_makara"
return ActiveRecord::Base.connection.without_sticking do
yield
end
end
yield
end
end
end
Any ideas?
In normal usage from database.yml, I don't really understand any window that exists where the connection is of any other class.
Can you post your yml file? Any particularly interesting connection code?
Assuming it does switch and you want this code to run correctly, maybe respond_to? would be better in the if statement.
maybe whateer object it is actually does have a config variable and it loads everything in.
@bleonard: Just to follow up on this: We found that this was occurring when calling connection.close explicitly in a thread block, e.g.:
Thread.new do
# ActiveRecord operations
ActiveRecord::Base.connection.close
end
Using ActiveRecord::Base.connection_pool.with_connection instead, where the connection is yielded from the pool, seems to have resolved the issue.
Hi @tbloncar I am also seeing the same issue. can you please confirm if
we need to replace
return ActiveRecord::Base.connection.without_sticking do
yield
end
with
return ActiveRecord::Base.connection_pool.with_connection do
yield
end
@aksharj My memory is a little lacking here, but as I recall, our application had some code that called ActiveRecord::Base.connection.close explicitly because it was establishing a new connection per thread rather than checking one out of the pool. This resulted in the new connection not having the Makara wrapper, which meant that the without_sticking method was not available on the connection. We moved to wrapping our ActiveRecord operations in new threads with ActiveRecord::Base.connection_pool.with_connection, and this eliminated the new, non-Makara-wrapped connections. More here on how to use this.
If this is indeed your issue, you should be able to use ActiveRecord::Base.connection.without_sticking reliably once you eliminate the rogue connections.
thanks @tbloncar for your reply, I think our scenario is little different, we upgraded rails app from 4 to 5 and ActiveRecord::Base.connection.without_sticking has stopped working since then.
However if I use your proposed solution it works. so I guess I will use it :D