falcon icon indicating copy to clipboard operation
falcon copied to clipboard

Railtie not loading

Open p8 opened this issue 1 year ago • 3 comments

I've added Falcon to the Rails TechEmpower benchmark: https://github.com/TechEmpower/FrameworkBenchmarks/pull/9339

I had to set the isolation_level to :fiber by hand to make it work. https://github.com/p8/FrameworkBenchmarks/blob/f7822a3d79689164e372fba05be4ee744b1f42a4/frameworks/Ruby/rails/config/application.rb#L55

Otherwise the following error would occur:

$ ./tfb --test rails-falcon --mode verify
...
rails-falcon: {"time":"2024-10-23T08:13:36+00:00","severity":"error","oid":3416,"pid":18,"subject":"Protocol::Rack::Adapter::Rack3","annotation":"Reading HTTP/1.1 requests for Async::HTTP::Protocol::HTTP1::Server.","event":{"type":"failure","root":"/rails","class":"NoMethodError","message":"\u001b[1mundefined method 'map_types!' for nil (\u001b[1;4mNoMethodError\u001b[m\u001b[1m)\u001b[m\n\n\u001b[1m              result = conn.async_exec(sql).map_types!(@type_map_for_results).values\u001b[m\n\u001b[1m                                           ^^^^^^^^^^^\u001b[m","backtrace":
["/usr/local/bundle/gems/activerecord-7.2.1.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:19:in 'block (2 levels) in ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#query'",
"/usr/local/bundle/gems/activerecord-7.2.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:1004:in 'block in ActiveRecord::ConnectionAdapters::AbstractAdapter#with_raw_connection'",
"/usr/local/bundle/gems/activesupport-7.2.1.1/lib/active_support/concurrency/null_lock.rb:9:in 'ActiveSupport::Concurrency::NullLock#synchronize'",
"/usr/local/bundle/gems/activerecord-7.2.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:976:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#with_raw_connection'",
"/usr/local/bundle/gems/activerecord-7.2.1.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:18:in 'block in ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#query'",
"/usr/local/bundle/gems/activesupport-7.2.1.1/lib/active_support/notifications/instrumenter.rb:58:in 'ActiveSupport::Notifications::Instrumenter#instrument'",
"/usr/local/bundle/gems/activerecord-7.2.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:1119:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#log'",
"/usr/local/bundle/gems/activerecord-7.2.1.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:17:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#query'",
"/usr/local/bundle/gems/activerecord-7.2.1.1/lib/active_record/connection_adapters/abstract/database_statements.rb:110:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#query_values'",
"/usr/local/bundle/gems/activerecord-7.2.1.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:35:in 'ActiveRecord::ConnectionAdapters::SchemaStatements#data_sources'"

p8 avatar Oct 23 '24 08:10 p8

I wonder if it's load order dependent?

https://github.com/socketry/falcon/blob/main/lib/falcon.rb#L10

ioquatix avatar Oct 23 '24 09:10 ioquatix

Yes, it could be that Rails isn't loaded there yet.

p8 avatar Oct 23 '24 09:10 p8

I wonder what the best strategy would be, e.g.

begin
  require 'railtie'
  ...
rescue LoadError 
  # Ignore
end

ioquatix avatar Oct 23 '24 09:10 ioquatix

I just hit this issue trying falcon in a new rails app:

$ bundle remove puma
$ bundle add falcon falcon-rails
$ rails s
Bundler::Runtime#require': There was an error while trying to load the gem 'falcon'. (Bundler::GemRequireError)
Gem Load Error is: uninitialized constant Falcon::Rails::Railtie

bundle exec falcon serve -b http://localhost:3000 seem to work ok, I guess I'll use that 😅

retorted avatar Oct 08 '25 13:10 retorted

This worked for me:

samuel@Sakura ~/D/tmp> rails new myproject
      create  
      create  README.md
      create  Rakefile
      create  .ruby-version
      create  config.ru
      create  .gitignore
      create  .gitattributes
      create  Gemfile
         run  git init from "."
Initialized empty Git repository in /Users/samuel/Developer/tmp/myproject/.git/
      create  app
      create  app/assets/stylesheets/application.css
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/jobs/application_job.rb
      create  app/mailers/application_mailer.rb
      create  app/models/application_record.rb
      create  app/views/layouts/application.html.erb
      create  app/views/layouts/mailer.html.erb
      create  app/views/layouts/mailer.text.erb
      create  app/views/pwa/manifest.json.erb
      create  app/views/pwa/service-worker.js
      create  app/assets/images
      create  app/assets/images/.keep
      create  app/controllers/concerns/.keep
      create  app/models/concerns/.keep
      create  bin
      create  bin/brakeman
      create  bin/dev
      create  bin/rails
      create  bin/rake
      create  bin/rubocop
      create  bin/setup
      create  bin/thrust
      create  Dockerfile
      create  .dockerignore
      create  bin/docker-entrypoint
      create  .rubocop.yml
      create  .github/workflows
      create  .github/workflows/ci.yml
      create  .github/dependabot.yml
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/cable.yml
      create  config/puma.rb
      create  config/storage.yml
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/assets.rb
      create  config/initializers/content_security_policy.rb
      create  config/initializers/cors.rb
      create  config/initializers/filter_parameter_logging.rb
      create  config/initializers/inflections.rb
      create  config/initializers/new_framework_defaults_8_0.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/master.key
      append  .gitignore
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  lib
      create  lib/tasks
      create  lib/tasks/.keep
      create  log
      create  log/.keep
      create  public
      create  public/400.html
      create  public/404.html
      create  public/406-unsupported-browser.html
      create  public/422.html
      create  public/500.html
      create  public/icon.png
      create  public/icon.svg
      create  public/robots.txt
      create  script
      create  script/.keep
      create  tmp
      create  tmp/.keep
      create  tmp/pids
      create  tmp/pids/.keep
      create  vendor
      create  vendor/.keep
      create  test/fixtures/files
      create  test/fixtures/files/.keep
      create  test/controllers
      create  test/controllers/.keep
      create  test/mailers
      create  test/mailers/.keep
      create  test/models
      create  test/models/.keep
      create  test/helpers
      create  test/helpers/.keep
      create  test/integration
      create  test/integration/.keep
      create  test/test_helper.rb
      create  test/system
      create  test/system/.keep
      create  test/application_system_test_case.rb
      create  storage
      create  storage/.keep
      create  tmp/storage
      create  tmp/storage/.keep
      remove  config/initializers/cors.rb
      remove  config/initializers/new_framework_defaults_8_0.rb
         run  bundle install --quiet
         run  bundle lock --add-platform=x86_64-linux
Writing lockfile to /Users/samuel/Developer/tmp/myproject/Gemfile.lock
         run  bundle lock --add-platform=aarch64-linux
Writing lockfile to /Users/samuel/Developer/tmp/myproject/Gemfile.lock
         run  bundle binstubs bundler
       rails  importmap:install
       apply  /Users/samuel/.gem/ruby/3.4.5/gems/importmap-rails-2.2.2/lib/install/install.rb
  Add Importmap include tags in application layout
      insert    app/views/layouts/application.html.erb
  Create application.js module as entrypoint
      create    app/javascript/application.js
  Use vendor/javascript for downloaded pins
      create    vendor/javascript
      create    vendor/javascript/.keep
  Configure importmap paths in config/importmap.rb
      create    config/importmap.rb
  Copying binstub
      create    bin/importmap
         run  bundle install --quiet
       rails  turbo:install stimulus:install
       apply  /Users/samuel/.gem/ruby/3.4.5/gems/turbo-rails-2.0.17/lib/install/turbo_with_importmap.rb
  Import Turbo
      append    app/javascript/application.js
  Pin Turbo
      append    config/importmap.rb
         run  bundle install --quiet
       apply  /Users/samuel/.gem/ruby/3.4.5/gems/stimulus-rails-1.3.4/lib/install/stimulus_with_importmap.rb
  Create controllers directory
      create    app/javascript/controllers
      create    app/javascript/controllers/index.js
      create    app/javascript/controllers/application.js
      create    app/javascript/controllers/hello_controller.js
  Import Stimulus controllers
      append    app/javascript/application.js
  Pin Stimulus
  Appending: pin "@hotwired/stimulus", to: "stimulus.min.js"
      append    config/importmap.rb
  Appending: pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
      append    config/importmap.rb
  Pin all controllers
  Appending: pin_all_from "app/javascript/controllers", under: "controllers"
      append    config/importmap.rb
         run  bundle install --quiet
         run  bundle binstubs kamal
         run  bundle exec kamal init
Created configuration file in config/deploy.yml
Created .kamal/secrets file
Created sample hooks in .kamal/hooks
       force  .kamal/secrets
       force  config/deploy.yml
       rails  solid_cache:install solid_queue:install solid_cable:install
      create  config/cache.yml
      create  db/cache_schema.rb
        gsub  config/environments/production.rb
      create  config/queue.yml
      create  config/recurring.yml
      create  db/queue_schema.rb
      create  bin/jobs
        gsub  config/environments/production.rb
      create  db/cable_schema.rb
       force  config/cable.yml
samuel@Sakura ~/D/tmp> cd myproject/
samuel@Sakura ~/D/t/myproject (main)> bundle remove puma
Removing gems from /Users/samuel/Developer/tmp/myproject/Gemfile
puma (>= 5.0) was removed.
samuel@Sakura ~/D/t/myproject (main)> bundle add falcon falcon-rails
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Fetching gem metadata from https://rubygems.org/.........
Fetching async 2.34.0
Installing async 2.34.0
samuel@Sakura ~/D/t/myproject (main)> rails s
=> Booting Falcon v0.52.3
=> Rails 8.0.3 application starting in development http://localhost:3000
=> Run `bin/rails server --help` for more startup options
 0.72s     info: process_action.action_controller: Reading HTTP/1.1 requests for Async::HTTP::Protocol::HTTP1::Server. [ec=0x1c90] [pid=14409] [2025-10-09 10:37:49 +1300]
               | {
               |   "controller": "Rails::WelcomeController",
               |   "action": "index",
               |   "format": "html",
               |   "method": "GET",
               |   "path": "/",
               |   "status": 200,
               |   "view_runtime": 7.287999987602234,
               |   "db_runtime": 0.0,
               |   "queries_count": 0,
               |   "cached_queries_count": 0,
               |   "source_address": "::1",
               |   "allocations": 26150,
               |   "duration": 56.728999972343445
               | }

Are you able to try that and let me know if there is something different between our systems?

ioquatix avatar Oct 08 '25 21:10 ioquatix

Huh! It works... and now I can't replicate it in my other project either. Sorry for the false alarm, looks like it was some kind of gem-loading gremlins on my end. Don't feed them after midnight! 😅

retorted avatar Oct 09 '25 11:10 retorted