Dispatcher.to_prepare with script/server and mongrel

I am using the Dispatcher/config.to_prepare hook to configure my application, but mongrel plays a trick with us.

The problem with running this with script/server is this:

1) Dispatcher, at line 160, sets self.preparation_callbacks = 2) Dispatcher gets loaded twice, once by the initalizer, and once by mongrel:

./script/../config/../vendor/rails/railties/lib/initializer.rb:4 /opt/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel/rails.rb:145:in `rails'

Since the first requires dispatcher with the full path, and the other with just 'dispatcher', the file gets loaded twice (see footnote in pickaxe p117). The second load happens after all environment stuff has been loaded, and wipes our callbacks.

It looks like it works OK in production, it's just when run with script/server.

Two suggestions for fixing, which both work because we're not reloading the Dispatcher between requests:

1) Add an "unless defined? Dispatcher" to the defining of the Dispatcher class, or just to line 160 (which resets the preparation_callbacks array)

2) Change Dispatcher.rb:160 to read "self.preparation_callbacks ||= ", so it's left alone if already defined.

Anything better?

//Lars

Lars, why are you sending this 6 or 7 times? Hopefully it's just google groups being stupid and not you.

The answer to your problem is probably just don't do that. There's many other ways to setup configuration information--mongrel.conf, environment.rb, production.rb--that I'm sure you could find an alternative way.

Then, report your problem to the rails trac bug tracker and wait for a resolution. Make sure you reduce your bug to the simplest demonstration code possible and give clear steps for repeating it.

Finally, if you don't mind modifying the mongrel source, find the place where this file is required and change it to match the original require so that it's not done twice.

Yeah, Google Groups kept throwing up an error page, and when I went to look, nothing had been posted. So sorry about that.

I was talking about this with DHH at RailsConf in London, and I haven't found a good way to configure my apps. I used to just set GLOBAL_CONSTANTS in my environment.rb files, but that's ugly, so I changed to setting it with cattr_accessor's on ApplicationController. However, this gets reloaded between each request, so you need the to_prepare hook.

Except it breaks under development as described above, and it never gets loaded under testing at all, because testing doesn't use the dispatcher to process requests.

What I'm really looking for is a method for initializing my application, which lets me set the variables as cattr_accessors on the classes where they belong, and which lets me set default settings in environment.rb and override those with more specific values in the other environment/*.rb's.

If to_prepare isn't it, what's the recommended way to initialize your app?

//Lars

If to_prepare isn't it, what's the recommended way to initialize your app?

to_prepare or config.after_initialize are there for exactly this, depending on what you're doing.

For your test and production.rb, just use config.after_initialize. The only reason you really need to_prepare is when you're worried about the class reloading in development.

Ideally mongrel shouldn't be causing Dispatcher to be required twice, can you give us a simple test case in a trac ticket? Or perhaps give zed one for mongrel?