makara icon indicating copy to clipboard operation
makara copied to clipboard

without_sticking failing as MakaraMysql2Adapter disappears?

Open schlenks opened this issue 9 years ago • 5 comments

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?

schlenks avatar Jul 30 '16 14:07 schlenks

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 avatar Sep 09 '16 17:09 bleonard

@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.

tbloncar avatar Apr 20 '18 22:04 tbloncar

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 avatar Dec 29 '22 00:12 aksharj

@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.

tbloncar avatar Dec 29 '22 05:12 tbloncar

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

aksharj avatar Mar 18 '23 15:03 aksharj