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.

Cheers, Will

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.

Thoughts?

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 compatibility.