markbates / configatron

A super cool, simple, and feature rich configuration system for Ruby apps.

Home Page:http://www.metabates.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

What is the right / best place to store configatron configuration in a Rails app?

konung opened this issue · comments

Hello,
I'm cross-posting this from stackoverflow as I don't seem to get any views on this question ( just 3 in over 24 hours :( ). Anyways I'm trying out configatron for my Rails 3.1 app and it's a great tool (thank you, markbates!) - but here is my question:

I'm using configatron gem for a new Rails app that is backed by ActiveRecord. Some of my configatron settings are set in a file and some are pulled from DB, as they will change from time to time, here are a couple of lines from my configatron.rb

configatron.app.uptime.start = Time.now
configatron.email.signature = Setting.where(:keyname => "email_signature").first.value.to_s unless Setting.where(:keyname => "email_signature").first.nil?

Since this app sends multuple emails from multiple mailers - that is a good way to keep this global config in one place, plus it reduces db lookups for signature. If for some reason site admin decides to change it - they can do it through web admin interface that will update my settings table ( tied to Setting model).

This is all jolly & good, however what is the best place to store configatron.rb? Right now it's sitting in my initializers folder. Which means it will load once on application startup - which is good, however if one of the settings changes - site admin decides to tweek email signature to mention a new promotional website - in order for the change to take effect - I would need to restart app ( I'm running passenger - so it trivial to do touch tmp/restart.txt from code). However that means other configatron settings that I don't wont to reset ( such as my uptime start timestamp) will be reset as well, plus if somebody is in a middle of some transaction I will most likely break it.

So what is a better place to move my configatron.rb and load from so that it would allow for
loading once on startup and then changing some configs without and app restart?

Thanks.

The initializers folder is the right place. If you look at the readme,
I think, or definitely the source there's a Configatron::Rails object
which will load up config files based on env.

If you want to pull stuff from a db or have config settings that may
change you should check out Configatron::Dynamic or
Configatron::Delayed config settings. Again it should be in the
readme.

Hope this helps. I'm on my phone right now so I can post exact details. Sorry.

Sent from my iPhone

On Oct 13, 2011, at 9:43 PM, Nick Gorbikoff
reply@reply.github.com
wrote:

Hello,
I'm cross-posting this from stackoverflow as I don't seem to get any views on this question ( just 3 in over 24 hours :( ). Anyways I'm trying out configatron for my Rails 3.1 app and it's a great tool (thank you, markbates!) - but here is my question:

I'm using configatron gem for a new Rails app that is backed by ActiveRecord. Some of my configatron settings are set in a file and some are pulled from DB, as they will change from time to time, here are a couple of lines from my configatron.rb

configatron.app.uptime.start = Time.now
configatron.email.signature = Setting.where(:keyname => "email_signature").first.value.to_s unless Setting.where(:keyname => "email_signature").first.nil?

Since this app sends multuple emails from multiple mailers - that is a good way to keep this global config in one place, plus it reduces db lookups for signature. If for some reason site admin decides to change it - they can do it through web admin interface that will update my settings table ( tied to Setting model).

This is all jolly & good, however what is the best place to store configatron.rb? Right now it's sitting in my initializers folder. Which means it will load once on application startup - which is good, however if one of the settings changes - site admin decides to tweek email signature to mention a new promotional website - in order for the change to take effect - I would need to restart app ( I'm running passenger - so it trivial to do touch tmp/restart.txt from code). However that means other configatron settings that I don't wont to reset ( such as my uptime start timestamp) will be reset as well, plus if somebody is in a middle of some transaction I will most likely break it.

So what is a better place to move my configatron.rb and load from so that it would allow for
loading once on startup and then changing some configs without and app restart?

Thanks.

Reply to this email directly or view it on GitHub:
#24

Hi Mark!
Thanks for your reply & gem!

I looked at Dynamic & Delayed and unless I'm not reading the docs right, this is not what I'm looking for. It says that Dynamic "Tells Configatron to always execute the block at runtime. The results will never be cached." - in rdoc and in readme on github - it says for your Dynamic example: "Each time you call configatron.current.time it will return a new value to you. While this seems a bit useless, it is pretty useful if you have ever changing configurations."

So in my example configatron.email.signature = Setting.where(:keyname => "email_signature").first.value.to_s unless Setting.where(:keyname => "email_signature").first.nil? will do a DB call every time I try to use the email signature? Is that correct?
I'm trying to avoid doing it - I only want that to be executed at startup and then if I specifically tell it to reload ( such on edit action in my admin controller). This setting is not an "ever changing one", it will change once in a blue moon, but I want to be able to get the change without restarting the whole app.

Am I misreading the docs?

The way you're doing it right now configatron.email.signature will be set once during initialization value to whatever is in your db. I would, recommend using the Configatron::Delayed stuff for that. That will delay the execution of that setting until the first time it's accessed. That's useful when pulling stuff from a db in case the db hasn't been initialized yet. It will then cache the result and not perform the query again.

Your other question, about updating the db occasionally and setting the new value to configatron, is not an easy one. It's plagued configuration systems since the dawn of time. Imagine you have 2+ web servers. You go into your admin console in on one server and update the db with the new setting you want. How do you propagate that to the other servers? If you use the Configatron::Dynamic it will also pull the value from the db, that way you always have the latest value. However, now you're doing a DB call every time you call the config setting. So what do you do?

The answer is there is no good way. You would need to message each server to tell them to either reload their configuration settings or to set that one setting to the new value. It's not an easy problem to solve, and unfortunately I don't have a ready answer for you. Sorry.

That's what I figured, but wanted to validate with the config pro :-) Thanks Mark. Still going to use you gem for configs, but I guess I will have to do that db query...

Thanks