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

Add Railties/Engines #506

Merged
merged 53 commits into from
May 7, 2021
Merged

Add Railties/Engines #506

merged 53 commits into from
May 7, 2021

Conversation

bkeepers
Copy link
Collaborator

@bkeepers bkeepers commented Mar 18, 2021

This adds Railties/Engines to remove as much manual configuration as possible when using flipping in a Rails app.

  • require 'flipper' sets up middleware
  • require 'flipper-cloud' configures and mounts app
  • require 'flipper-ui configures and mounts app skipping since it needs some kind of auth
  • Doc all the things

This is part of #500 to improve the onboarding experience.

@bkeepers bkeepers changed the title Add Add Railties/Engines Mar 18, 2021
Base automatically changed from flipper-id to set-defaults March 19, 2021 12:30
Base automatically changed from set-defaults to master March 19, 2021 12:46
@bkeepers bkeepers mentioned this pull request Mar 19, 2021
7 tasks
lib/flipper/cloud/routes.rb Outdated Show resolved Hide resolved
* origin/master:
  Use #load instead of #require for all adapter specs
  Use Kernel#load to load adapter in spec
  Only run specs on pr and push to master
  Run specs in random order
  Re-raise connection errors in CI
  Handle Redis connection failure too
  Don't skip on CI
  Remove deprecated DalliStore
  Skip adapter tests if connection fails
  Remove flipper-rails references for now
  README driven development for onboarding improvements
* deprecate_sync_method:
  Deprecate superflous sync_method setting
lib/flipper/railtie.rb Outdated Show resolved Hide resolved
lib/flipper-cloud.rb Outdated Show resolved Hide resolved
@bkeepers
Copy link
Collaborator Author

bkeepers commented May 4, 2021

For some reason I'm having a hard time picturing how Flipper.configure in an initializer would get things setup soon enough for the rails engine to pickup the changes. But I don't know about load order for stuff like that. Have you tried it in a rails app with different memoize options and stuff?

Thanks for bringing this up. I thought based these docs in rails/application.rb that the Railtie initializers would run after config/initializers/*:

The application is also responsible for setting up and executing the booting
process. From the moment you require "config/application.rb" in your app,
the booting process goes like this:

  1. require "config/boot.rb" to set up load paths
  2. require railties and engines
  3. Define Rails.application as "class MyApp::Application < Rails::Application"
  4. Run config.before_configuration callbacks
  5. Load config/environments/ENV.rb
  6. Run config.before_initialize callbacks
  7. Run Railtie#initializer defined by railties, engines and application.
    One by one, each engine sets up its load paths, routes and runs its config/initializers/* files.
  8. Custom Railtie#initializers added by railties, engines and applications are executed
  9. Build the middleware stack and run to_prepare callbacks
  10. Run config.before_eager_load and eager_load! if eager_load is true
  11. Run config.after_initialize callbacks

However, I tested it in a real app and that was not the case. So I've updated the Railtie to explicitly run after config/initializers/*, and I've updated the cloud engine to mount the route after initialize.

@bkeepers
Copy link
Collaborator Author

bkeepers commented May 4, 2021

@jnunemaker I tested this in a real app and had to rework configuration a little. Before 2bf2e82, Cloud::Engine would instantiate Flipper.instance to decide if the webhooks app should be mounted. This would cause it to attempt an HTTP request to sync on app boot, which is not ideal because it not only slows down the boot process, but could prevent the app from booting if an error occurred.

So as a result of cleaning some of that up, I ended up going full circle on the discussion about configuration and moved a few things back to Rails.application.config. These are only configuration that relate to this Rails integration (env_key, memoize, preload, and cloud_path). Configuring Flipper adapters still happens in Flipper.configuration. This feels better to me since they really only apply for the Rails integration.

@jnunemaker
Copy link
Collaborator

This AMAZING. Very excited.

I don't want to block shipping this, but some other things that would be nice to wrap up in rails config eventually:

  • enabling instrumentation with ActiveSupport::Notifications for cloud and default. I usually use these. Probably good on by default and config to disable ala memoize.
  • log flipper calls in rails log require "flipper/instrumentation/log_subscriber" if ENV.fetch("FLIPPER_LOG", "0").to_i == 1. This is usually something that I protect with env var but it could be on in dev or on based on config. It would need to set instrumented for dsl instance as well.

I should be done kicking the tires today. Tested a couple apps. I just want to check all the config with the flipper cloud default rails app to ensure things are working.

@bkeepers
Copy link
Collaborator Author

bkeepers commented May 6, 2021

ooh, good call. f81b2ea sets instrumentor in both the Railtie and Cloud::Engine. LogSubscriber already checks if logger.debug?, so seems to me like it's fine to just require in the railtie without any configuration. If someone really wanted to change or disable it, I think they could set Flipper::Instrumentation::LogSubscriber.logger = Logger.new(…) .

@jnunemaker jnunemaker merged commit 74c5b70 into master May 7, 2021
@jnunemaker jnunemaker deleted the railties branch May 7, 2021 00:23
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

Successfully merging this pull request may close these issues.

2 participants