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?