Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.1.0 with single threaded puma results in "all pooled connections were in use" #883

Closed
frank-west-iii opened this issue Sep 17, 2024 · 6 comments

Comments

@frank-west-iii
Copy link

The newer VALUE_TO_TEXT_WARNING check is causing the issue here after some digging. I'm unsure how to resolve this issue while keeping a single threaded puma instance running. Appreciate any insight you might have. I can currently run with multiple threads, but I like running single threaded for easier debugging in my puma.

ruby: 3.2.5
rails: 7.0.8.4

Locally I run puma in single mode with a single thread:

The output I end up with after upgrading to 1.1.0 is as follows:

=> Booting Puma
=> Rails 7.0.8.4 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.4.2 (ruby 3.2.5-p208) ("The Eagle of Durango")
*  Min threads: 1
*  Max threads: 1
*  Environment: development
*          PID: 24685
* Listening on http://0.0.0.0:3001
Use Ctrl-C to stop
Started GET "/cable" for 127.0.0.1 at 2024-09-17 12:13:10 -0700

ActiveRecord::ConnectionTimeoutError (could not obtain a connection from the pool within 5.000 seconds (waited 5.007 seconds); all pooled connections were in use):

Changing my puma config to two threads results in the application working just fine:

=> Booting Puma                                                                                                                                                                                                                                                                                           => Rails 7.0.8.4 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.4.2 (ruby 3.2.5-p208) ("The Eagle of Durango")
*  Min threads: 2
*  Max threads: 2
*  Environment: development
*          PID: 25235
* Listening on http://0.0.0.0:3001                                                                                                                                                                                                                                                                        Use Ctrl-C to stop
Started GET "/user_settings/edit" for 127.0.0.1 at 2024-09-17 12:14:27 -0700
  ActiveRecord::SchemaMigration Pluck (2.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC                                                                                                                                                           Your database needs migrated to use the latest Flipper features.
        See https://github.com/flippercloud/flipper/issues/557
   (5.2ms)  SELECT "flipper_features"."key" AS feature_key, "flipper_gates"."key", "flipper_gates"."value" FROM "flipper_features" LEFT OUTER JOIN "flipper_gates" ON "flipper_features"."key" = "flipper_gates"."feature_key"                                                                            Processing by UserSettingsController#edit as HTML

This pointed me to look at the new migration check.

I was able to comment out the warn VALUE_TO_TEXT_WARNING in the initializer and the app boots up just fine.

# lib/flipper/adapters/active_record.rb:57

      def initialize(options = {})
        @name = options.fetch(:name, :active_record)
        @feature_class = options.fetch(:feature_class) { Feature }
        @gate_class = options.fetch(:gate_class) { Gate }

        # warn VALUE_TO_TEXT_WARNING if value_not_text?
      end

The app boots up and works fine without migration check in the initializer and in single threaded mode.

=> Booting Puma                                                                                                                                                                                                                                                                                           => Rails 7.0.8.4 application starting in development                                                                                                                                                                                                                                                      => Run `bin/rails server --help` for more startup options
Puma starting in single mode...                                                                                                                                                                                                                                                                           * Puma version: 6.4.2 (ruby 3.2.5-p208) ("The Eagle of Durango")                                                                                                                                                                                                                                          *  Min threads: 1                                                                                                                                                                                                                                                                                         *  Max threads: 1
*  Environment: development
*          PID: 31741
* Listening on http://0.0.0.0:3001
Use Ctrl-C to stop
Started GET "/user_settings/edit" for 127.0.0.1 at 2024-09-17 12:21:22 -0700
  ActiveRecord::SchemaMigration Pluck (1.4ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
   (10.8ms)  SELECT "flipper_features"."key" AS feature_key, "flipper_gates"."key", "flipper_gates"."value" FROM "flipper_features" LEFT OUTER JOIN "flipper_gates" ON "flipper_features"."key" = "flipper_gates"."feature_key"
Processing by UserSettingsController#edit as HTML
@frank-west-iii
Copy link
Author

The following change is simple enough where it allows me to keep my single thread settings and it works. Just a curious case of unexpected breakage with my current setup that hasn't been a problem for some time.

Something just feels like this is holding onto some connection it shouldn't, but I'm very much not an expert in this area.

diff --git a/config/database.yml b/config/database.yml
index b9f9f5fe5..552814532 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -1,7 +1,7 @@
 default: &default
   adapter: postgresql
   encoding: utf8
-  pool: <%= ENV.fetch('RAILS_MAX_THREADS', 5) %>
+  pool: <%= ENV.fetch('RAILS_MAX_THREADS', 5).to_i * 2 %>
 
 development:
   primary: &primary

@bkeepers
Copy link
Collaborator

I was able to comment out the warn VALUE_TO_TEXT_WARNING in the initializer and the app boots up just fine.

Can you add puts caller in it's place and share the backtrace? I'm curious if something is causing the adapter to initialize during the app boot process before Puma forks the worker process, and somehow the it's holding on to the connections.

@frank-west-iii
Copy link
Author

I have a second app that works just fine with a similar setup so I am trying to find what the difference is between the two apps. While I am digging here are the logs in case something jumps out.

Here's the log up to the handling of the request:

development.log

Isolated trace calls related to puma pulled from the logs attached.

[
 "/Users/frank/code/order/order/config/initializers/flipper.rb:5:in `new'",
 "/Users/frank/code/order/order/config/initializers/flipper.rb:5:in `block (2 levels) in <main>'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/adapter_builder.rb:41:in `to_adapter'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/configuration.rb:29:in `adapter'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/engine.rb:55:in `block (3 levels) in <class:Engine>'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/configuration.rb:65:in `default'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper.rb:46:in `instance'",
 "/Users/frank/code/order/order/config/routes/developer_routes.rb:3:in `block in draw'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/routing/mapper.rb:871:in `scope'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/routing/mapper.rb:1000:in `constraints'",
 "/Users/frank/code/order/order/config/routes/developer_routes.rb:1:in `draw'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/routing/mapper.rb:1623:in `instance_eval'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/routing/mapper.rb:1623:in `draw'",
 "/Users/frank/code/order/order/config/routes.rb:45:in `block in <main>'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/routing/route_set.rb:428:in `instance_exec'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/routing/route_set.rb:428:in `eval_block'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/routing/route_set.rb:410:in `draw'",
 "/Users/frank/code/order/order/config/routes.rb:6:in `<main>'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/application/routes_reloader.rb:50:in `load'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/application/routes_reloader.rb:50:in `block in load_paths'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/application/routes_reloader.rb:50:in `each'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/application/routes_reloader.rb:50:in `load_paths'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/application/routes_reloader.rb:24:in `reload!'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/application/routes_reloader.rb:38:in `block in updater'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/activesupport-7.0.8.4/lib/active_support/file_update_checker.rb:83:in `execute'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/application/routes_reloader.rb:13:in `execute'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/application/finisher.rb:158:in `block in <module:Finisher>'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/initializable.rb:32:in `instance_exec'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/initializable.rb:32:in `run'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/initializable.rb:61:in `block in run_initializers'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/tsort.rb:228:in `block in tsort_each'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/tsort.rb:431:in `each_strongly_connected_component_from'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/tsort.rb:349:in `block in each_strongly_connected_component'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/tsort.rb:347:in `each'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/tsort.rb:347:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/tsort.rb:347:in `each_strongly_connected_component'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/tsort.rb:226:in `tsort_each'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/tsort.rb:205:in `tsort_each'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/initializable.rb:60:in `run_initializers'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/application.rb:372:in `initialize!'",
 "/Users/frank/code/order/order/config/environment.rb:5:in `<top (required)>'",
 "config.ru:3:in `require_relative'",
 "config.ru:3:in `block in <main>'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/builder.rb:116:in `eval'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/builder.rb:116:in `new_from_string'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/builder.rb:105:in `load_file'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/builder.rb:66:in `parse_file'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/configuration.rb:368:in `load_rackup'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/configuration.rb:290:in `app'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/runner.rb:162:in `load_and_bind'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/single.rb:44:in `run'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/launcher.rb:194:in `run'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/cli.rb:75:in `run'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/bin/puma:10:in `<top (required)>'",
 "bin/puma:29:in `load'",
 "bin/puma:29:in `<main>'"
]
[
 "/Users/frank/code/order/order/config/initializers/flipper.rb:5:in `new'",
 "/Users/frank/code/order/order/config/initializers/flipper.rb:5:in `block (2 levels) in <main>'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/adapter_builder.rb:41:in `to_adapter'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/configuration.rb:29:in `adapter'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/engine.rb:55:in `block (3 levels) in <class:Engine>'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/configuration.rb:65:in `default'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper.rb:46:in `instance'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/3.2.0/forwardable.rb:234:in `memoizing?'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/middleware/memoizer.rb:67:in `memoized_call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/flipper-1.3.1/lib/flipper/middleware/memoizer.rb:45:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/static.rb:23:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/omniauth-2.1.1/lib/omniauth/strategy.rb:202:in `call!'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/omniauth-2.1.1/lib/omniauth/strategy.rb:169:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/omniauth-2.1.1/lib/omniauth/strategy.rb:202:in `call!'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/omniauth-2.1.1/lib/omniauth/strategy.rb:169:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/bullet-7.0.7/lib/bullet/rack.rb:14:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/scout_apm-4.1.1/lib/scout_apm/instant/middleware.rb:53:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/scout_apm-4.1.1/lib/scout_apm/middleware.rb:20:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/warden-1.2.9/lib/warden/manager.rb:36:in `block in call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/warden-1.2.9/lib/warden/manager.rb:34:in `catch'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/warden-1.2.9/lib/warden/manager.rb:34:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/tempfile_reaper.rb:15:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/etag.rb:27:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/conditional_get.rb:27:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/head.rb:12:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/http/permissions_policy.rb:38:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/http/content_security_policy.rb:36:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/session/abstract/id.rb:266:in `context'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/session/abstract/id.rb:260:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/cookies.rb:704:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/activerecord-7.0.8.4/lib/active_record/migration.rb:638:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/activesupport-7.0.8.4/lib/active_support/callbacks.rb:99:in `run_callbacks'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/callbacks.rb:26:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/executor.rb:14:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/sentry-rails-5.12.0/lib/sentry/rails/rescued_exception_interceptor.rb:12:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/web-console-4.2.1/lib/web_console/middleware.rb:132:in `call_app'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/web-console-4.2.1/lib/web_console/middleware.rb:28:in `block in call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/web-console-4.2.1/lib/web_console/middleware.rb:17:in `catch'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/web-console-4.2.1/lib/web_console/middleware.rb:17:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/sentry-ruby-5.12.0/lib/sentry/rack/capture_exceptions.rb:28:in `block (2 levels) in call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/sentry-ruby-5.12.0/lib/sentry/hub.rb:251:in `with_session_tracking'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/sentry-ruby-5.12.0/lib/sentry-ruby.rb:387:in `with_session_tracking'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/sentry-ruby-5.12.0/lib/sentry/rack/capture_exceptions.rb:19:in `block in call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/sentry-ruby-5.12.0/lib/sentry/hub.rb:59:in `with_scope'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/sentry-ruby-5.12.0/lib/sentry-ruby.rb:367:in `with_scope'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/sentry-ruby-5.12.0/lib/sentry/rack/capture_exceptions.rb:18:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/show_exceptions.rb:29:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/rack/logger.rb:40:in `call_app'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/rack/logger.rb:25:in `block in call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/activesupport-7.0.8.4/lib/active_support/tagged_logging.rb:99:in `block in tagged'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/activesupport-7.0.8.4/lib/active_support/tagged_logging.rb:37:in `tagged'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/activesupport-7.0.8.4/lib/active_support/tagged_logging.rb:99:in `tagged'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/rack/logger.rb:25:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/sprockets-rails-3.4.2/lib/sprockets/rails/quiet_assets.rb:13:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/remote_ip.rb:93:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/request_store-1.5.1/lib/request_store/middleware.rb:19:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/request_id.rb:26:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/method_override.rb:24:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/runtime.rb:22:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/activesupport-7.0.8.4/lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/executor.rb:14:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/static.rb:23:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-2.2.9/lib/rack/sendfile.rb:110:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/actionpack-7.0.8.4/lib/action_dispatch/middleware/host_authorization.rb:138:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/webpacker-6.0.0.rc.6/lib/webpacker/dev_server_proxy.rb:25:in `perform_request'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/rack-proxy-0.7.7/lib/rack/proxy.rb:87:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/scout_apm-4.1.1/lib/scout_apm/instruments/middleware_summary.rb:58:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/railties-7.0.8.4/lib/rails/engine.rb:530:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/configuration.rb:272:in `call'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/request.rb:100:in `block in handle_request'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/thread_pool.rb:378:in `with_force_shutdown'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/request.rb:99:in `handle_request'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/server.rb:464:in `process_client'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/server.rb:245:in `block in run'",
 "/Users/frank/.asdf/installs/ruby/3.2.5/lib/ruby/gems/3.2.0/gems/puma-6.4.2/lib/puma/thread_pool.rb:155:in `block in spawn_thread'"
]

We were upgrading to the latest flipper and just tried to backtrack to which version broke for us. Here are the files relative to the caller trace on our side just in case they are helpful.

# config/initializers/flipper.rb

require 'flipper'
require 'flipper/adapters/active_record'

Flipper.configure do |config|
  config.adapter { Flipper::Adapters::ActiveRecord.new }
end

Flipper::UI.configure do |config|
  config.application_href = "/admin"
  config.cloud_recommendation = false
  config.confirm_fully_enable = true
  config.confirm_disable = true
  config.banner_text = Rails.env.titleize
  config.banner_class = Rails.env.production? ? "danger" : "warning"
  config.descriptions_source = lambda do |_keys|
    YAML.load_file(Rails.root.join("config/flipper_descriptions.yml"))
  end
  config.show_feature_description_in_list = true
end

# Groups
Flipper.register(:staff, &:staff?)

Flipper.register(:sellers) do |actor|
  actor.thing.is_a? Seller
end

Flipper.register(:buyers) do |actor|
  actor.thing.is_a? Buyer
end

Rails.application.configure do
  config.flipper.preload = lambda { |request|
    ["/assets", "/status"].none? { |path| request.path.start_with?(path) }
  }

  # This is not recommended, but we currently need to add groups to deal with the amount of actors
  # we have.
  config.flipper.actor_limit = false
end
# config/routes.rb

...
draw(:developer_routes)
# config/routes/developer_routes.rb

constraints StaffConstraint do
  # Flipper/Feature Flagging
  mount Flipper::UI.app(Flipper.instance), at: '/flipper'
end
# config/environment.rb

# Load the Rails application.
require_relative "application"

# Initialize the Rails application.
Rails.application.initialize!
# config/puma.rb

# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#

max_threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }
min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
threads min_threads_count, max_threads_count

# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port        ENV.fetch('PORT') { 3000 }

# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch('RAILS_ENV') { 'development' }

if ENV['WEB_CONCURRENCY'].to_i.positive?
  # Specifies the number of `workers` to boot in clustered mode.
  # Workers are forked web server processes. If using threads and workers together
  # the concurrency of the application would be max `threads` * `workers`.
  # Workers do not work on JRuby or Windows (both of which do not support
  # processes).
  workers ENV['WEB_CONCURRENCY']

  # Use the `preload_app!` method when specifying a `workers` number.
  # This directive tells Puma to first boot the application and load code
  # before forking the application. This takes advantage of Copy On Write
  # process behavior so workers use less memory.
  preload_app!

  # If you are preloading your application and using Active Record, it's
  # recommended that you close any connections to the database before workers
  # are forked to prevent connection leakage.
  before_fork do
    ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord)
  end

  # The code in the `on_worker_boot` will be called if you are using
  # clustered mode by specifying a number of `workers`. After each worker
  # process is booted, this block will be run. If you are using the `preload_app!`
  # option, you will want to use this block to reconnect to any threads
  # or connections that may have been created at application boot, as Ruby
  # cannot share connections between processes.
  #
  on_worker_boot do
    ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
  end
end

# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
# config.ru

# This file is used by Rack-based servers to start the application.

require_relative 'config/environment'

run Rails.application
Rails.application.load_server

@jnunemaker
Copy link
Collaborator

What happens if you change mount Flipper::UI.app(Flipper.instance), at: '/flipper' to mount Flipper::UI.app, at: '/flipper'. You shouldn't need the instance there. I think it's trying to load all the flipper stuff in your routes and that is causing the issue. Try that and let me know!

@frank-west-iii
Copy link
Author

Yup. That's what was causing it. Thanks a ton. Looks like we had a refactor that took out some basic auth from the routing and this was not changed over to Flipper, but leaving it out entirely works as well.

@jnunemaker
Copy link
Collaborator

jnunemaker commented Oct 29, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants