11

I'm trying to create async api with Goliath framework. Service should write to mysql, add messages to RabbitMQ and receive responses back. There also should be a separate admin application built with Rails. I have several questions about that:

Is there a way to effectively share models between Rails and Goliath? Is there any problems to use Activerecord or any other orm with em? Are there any best practices, configuration (connection pool size, driver) or other options about that? What i have to use to receive messages from AMQP? Would it better to build a separate eventmachine daemon or i can use somehow Goliath's one for that stuff? Thanks for advance.

gayavat
  • 18,910
  • 11
  • 45
  • 55

1 Answers1

5

Here's a quick hack to use ActiveRecord models in Goliath. With this approach you can use the model without using require, but you don't have the relationships on the model level. To get the has_many and belongs_to relationships (in this approach), I would load the model file and include the lines containing such words in the class definition loop below.

    require 'goliath'
    require 'active_record'
    require 'active_support'

    # The location of the Rails app to integrate
    RAILS_APP ||= ENV['HOME']+"/dev/qtrack"

    # Load the ActiveRecord database configuration, development settings
    configpath = File.join(RAILS_APP, "config", "database.yml")
    config = YAML::load_file(configpath)
    ActiveRecord::Base.establish_connection config["development"]

    # Set the names of all Rails models to a constant
    MODELS ||= []
    models_dir = File.join(RAILS_APP, "app", "models")
    model_names = Dir[models_dir+"/*.rb"]

    # Loop over each file name, define a class for each
    model_names.each do |fname|
      mname = File.basename(fname, '.rb').titleize.sub(/ /, '')
      eval %Q{
        class ::#{mname} < ActiveRecord::Base
        end
      }
      m = mname.constantize
      MODELS << m unless MODELS.include?(m)
    end

    class Hello < Goliath::API
      # default to JSON output, allow Yaml as secondary
      use Goliath::Rack::Render, ['json', 'yaml']

      def response(env)
        # Create a Hash with each model name and the object count
        models = MODELS.inject({}) {|hsh,model| hsh[model] = model.count; hsh }
        [200, {}, models.to_json ]
      end
    end

This is a hack based on your feedback.

ringe
  • 812
  • 6
  • 14
  • Btw: The ActiveRecord gem is 'activerecord', the require is as shown. – ringe Jun 25 '12 at 14:28
  • 1
    In your example you don't share model with rails. Also if we have much logic in models it isn't safe to simply require them. Synchronous logic decoupling is needed. Also as you know sqlite hasn't async driver – Bombazook Jun 26 '12 at 11:24
  • 1
    I've edited the example to show use of Rails models, without require. The problem with SQlite is best solved using a different database. – ringe Jun 27 '12 at 12:43