Rack freezing

Hi guys,

I notice that in the last week of 2.3.3 preparation the vendored rack
was removed, so we now need to install the gem.

Should rake rails:freeze:gems be extended to freeze in rack?

It was surprising to me that it this lateish change didn't maintain
what was effectively the old behaviour since rack had been bundled,
and GEM=rack rake gems:unpack won't freeze it in either currently
since (I assume) it's not listed as an environment dependency.


The situation for Rack is a little weird. Here's what I observed:

- when running Rails from installed gems, the call to load_rails_gem
will blow up unless Rack is installed. The code to set things up for
vendor/gems isn't even loaded for this part, so this will *always*
require Rack to be installed.

- when running from vendor/rails, the Rack gem can be frozen if
there's a config.gem line for it. It should be possible to unpack Rack
to vendor/gems and generate the specification file for it within
rails:freeze:gems, with some modification to the existing code.

But there are two objections I can think of here:

- "rake gems" still won't display the status of the Rack gem, as it
only looks at gems specified in environment.rb

- should this really be needed? I can see both views on whether Rack
is a part of the app or part of the server infrastructure. To give a
different example, most people would agree that freezing Passenger
wouldn't make a lot of sense. So the issue of bundling Rack may still
need some discussion.

--Matt Jones

Rails uses a lot of Rack functionality, so I think vendoring it makes
sense. Phusion Passenger tries very very hard to be compatible with
everything so it shouldn't be necessary to vendor it. On the other
hand, I'm not sure whether Rack provides any backwards compatibility
guarantees at all.

I don't think that vendoring Rack will even *work* on Passenger - I haven't tried it, but a casual reading of the FrameworkSpawner code shows that it loads the Rails gem (in preload_rails). With 2.3.3, this will blow up unless Rack is installed at the system level.

So encouraging users to freeze Rack will result in apps that break in some environments but not others (even 'smart-lv2' vs 'smart' spawning).

--Matt Jones

It seems to work - I added rack to config.gem and unpacked it, and it
deployed fine into our Passenger server environment.

So as far as I can see, automatically adding rack to the list of gem
dependencies, and automatically unpacking rack when rake
rails:freeze:gems is run, would solve the problem?

Actually, just realised rack is still installed as a gem, so ignore me
- haven't tested out that scenario properly.

You are right, it doesn't work at this time. But I can make it work.

With this I mean that Phusion Passenger vendors Rack as well in order
to work around broken applications. With a few tricks I can remove
this vendoring while still retaining compatibility.

Personally I don't mind Phusion Passenger depending on or vendoring in
Rack, as long as all the Ruby HTTP servers work the same way (perhaps
too difficult a thing to ask).

Mongrel doesn't depend on Rack, so ActionPack does. That sort of puts
the ball in Rails' court, and accordingly makes it seem to me like we
must freeze in Rack when we freeze in Rails (since the whole point of
freezing in is that you don't need to deploy anything else to make the
app work - aside from the HTTP server you're using, the mongrel gem in
this example).

But, that currently doesn't really match Passenger, as you say. So, I
wonder if someone could make just as strong a case that Mongrel should
be changed to depend on Rack and ActionPack should not.


Perhaps we need to assess which is more likely to lead to problems
with people deploying apps (which are not necessarily running latest
release of Rails). In other words, what's more likely to make
breaking changes that can't or won't be worked around - changes to the
API between HTTP server and Rack, or between Rack and Rails?

Looking at the number of commits Joshua had to make to keep Rails
up-to-date with Rack, I would have guessed the latter, in which case
yeah I'd still vote that we should vendor in Rack. People are more
likely to be able to upgrade Passenger, than they are to be able to
upgrade to the latest release of Rails just for updated Rack