yabeda-rb / yabeda-puma-plugin

Collects Puma web-server metrics from puma control panel
MIT License
70 stars 17 forks source link

Conditional plugin load #28

Open khataev opened 1 year ago

khataev commented 1 year ago

Hi! This question is mostly because of educational purposes, so not a real issue. Still, the problem is the following. I was looking in a ways to decrease memory consumption and tried to implement conditional loading of this gem and yabeda-prometheus gem based on environment variable. So it look like this:

Gemfile

gem "yabeda-puma-plugin", require: false
gem "yabeda-prometheus", require: false

config/puma.rb

if ENV.fetch("ENABLE_YABEDA", false)
  require "yabeda/puma/plugin"
  activate_control_app
  plugin :yabeda
end

routes.rb

  if Settings.yabeda.enabled
    require "yabeda/prometheus"
    mount Yabeda::Prometheus::Exporter => "/metrics"
  end

but all attempts to require these gems manually lead to this error:

require "yabeda/puma/plugin.rb"

NoMethodError: undefined method `already_configured?' for Yabeda:Module
from /Users/khataev/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/yabeda-0.11.0/lib/yabeda/railtie.rb:7:in `block in <class:Railtie>'

# or

require "yabeda/prometheus"

NoMethodError: undefined method `already_configured?' for Yabeda:Module
from /Users/khataev/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/yabeda-0.11.0/lib/yabeda/railtie.rb:7:in `block in <class:Railtie>'

# or even

require "yabeda"
NoMethodError: undefined method `already_configured?' for Yabeda:Module
from /Users/khataev/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/yabeda-0.11.0/lib/yabeda/railtie.rb:7:in `block in <class:Railtie>'

not sure to understand how everything works when those gems are loaded by bundler, but looks like there is something non-trivial around yabeda gem require (on which those two depend). Can you please explain?

Envek commented 1 year ago

Hey, sorry for the long wait.

It seems that if you already have Rails application initialized, then require "yabeda" tries to require its railtie before declaring essential methods of itself, and that railtie tries to execute after_initialize block in-place.

Probably, moving this railtie require to the end of file should help.