Using config vars/db connections in other classes

63 views
Skip to first unread message

Mark Quezada

unread,
Apr 30, 2012, 6:15:13 PM4/30/12
to golia...@googlegroups.com
Hi, 

I'm new to goliath and I'm having a little trouble conceptualizing some of the basic goliath patterns.

I've set up my config file and loaded a mongo db connection pool like so:

config['mongo'] = EM::Synchrony::ConnectionPool.new(:size => 10) do
  EM::Mongo::Connection.new('localhost', '1234', 1, {:reconnect_in => 1}).db('test')
end

And in my api endpoint I'd like to do something like this:

def response(env)
  test = TestClass.create({some_var: 'testing 123'})

  [200, {'Content-Type' => 'text/javascript'}, [{id: test.id}.to_json]]
end

The TestClass encapsulates some logic behind creating and saving this object in mongo. I also have to hit an API endpoint on creation before I can save the data in mongo.

Is there any way to have access to goliath's logger and database connections (env.config.mongo in this case I suppose) without explicitly passing them around everywhere?

More generally, how does one handle this sort of abstraction using goliath?

I guess I'm just not seeing the full picture yet. Any nudges in the right direction would be greatly appreciated.

Ilya Grigorik

unread,
Apr 30, 2012, 6:51:22 PM4/30/12
to golia...@googlegroups.com
To call the database within the API you have two methods: env['mongo'], or just "mongo", where the latter is just syntactic sugar which will lookup the constant in env hash. With that in mind, within any of the methods of the api, simply call to mongo and do any work you need. 

ex:

def response(env)
 user = create_user({..})

 [200, ..., ...]
end

def create_user(opts)
 #some logic
 mongo.insert {...}
 logger.info "Created user blah"

 # ...
end

ig

Mark Quezada

unread,
Apr 30, 2012, 7:35:41 PM4/30/12
to golia...@googlegroups.com
Thanks for the quick reply Ilya. So basically I should try to keep everything in the API classes/sub-classes directly?

I ask because in our case, this class is shared across multiple endpoints. For example, we have a Call.create, and a Call.hangup which are accessed through separate goliath endpoints currently. Something like this for creation:

def response(env)
  call = Call.create({
    originator: env.params['originator'],
    destination: env.params['destination'],
  }, config, logger)

  [200, {'Content-Type' => 'text/javascript'}, [{id: call.id}.to_json]]
end

... and for hangup:

def response(env)
  call = Call.find(env.params['id'], config, logger)
  call.hangup!

  [200, {'Content-Type' => 'text/javascript'}, []]
end

... notice that I pass in the config and logger vars so that I can access them from within the class.

I'm wrapping up functionality in this "Call" class because Call.create will create a call, send an api request to a freeswitch server, save the response, handle errors from freeswitch, etc. I also have several endpoints that use this same class to create different types of calls. TestCall, for example inherits from Call. I'm trying to keep from duplicating a lot of this functionality across endpoints.

I suppose I can make the Call class subclass Goliath::API directly. It just seemed a bit strange that my "model" class would inherit from the Goliath API class.

Am I just thinking about this wrong? Is Goliath::API intended for subclassing in this way?

Ilya Grigorik

unread,
Apr 30, 2012, 7:40:31 PM4/30/12
to golia...@googlegroups.com
On Mon, Apr 30, 2012 at 4:35 PM, Mark Quezada <ma...@mirthlab.com> wrote:
I suppose I can make the Call class subclass Goliath::API directly. It just seemed a bit strange that my "model" class would inherit from the Goliath API class.

Am I just thinking about this wrong? Is Goliath::API intended for subclassing in this way?

No what you're doing is right, you definitely don't need to (or should) subclass Goliath::API. Just pass in the env variable and/or the logger, etc, and do your work in there. Assuming you're using the class methods as shown above, they should still execute within the context of the request fiber and automatically pause/resume the execution via fiber callbacks.

ig

Mark Quezada

unread,
Apr 30, 2012, 8:06:34 PM4/30/12
to golia...@googlegroups.com
Great, thanks for the sanity check. I just wanted to make sure I wasn't going down the wrong path.

Lorgio Jimenez

unread,
Feb 19, 2014, 10:59:11 AM2/19/14
to golia...@googlegroups.com, ma...@mirthlab.com
So is there any way to have these connections outside of the Goliath::API class?  I'm not using em-activeRecord and so i don't have a base class to  "establish_connection". 

for example.

i have app.rb  which is my Goliath::API  file
i have my connection pool(em-mongo) setup in config/app.rb
but i'd like to seperate some of the business logic into other classes, (like app/models/my_model.rb)
It seems that unless when i call the MyModel class, if i don't pass the "mongo" attribute from the app.rb file, i won't get the connection.

Do i need to subclass it from Goliath::API? 
Reply all
Reply to author
Forward
0 new messages