Recently, I forked rack and created a feature [https://github.com/rack/rack/pull/245] that allows one to specify web server options as commands within config.ru, not only on the rackup command line or the comment line (#\) within config.ru. The need for this arises from new web server technologies like the ones typically used for Mongrel2 which need significantly more setup information than a simple Webrick or (legacy) Mongrel server.
Mongrel2 typically exchanges its web server requests and responses through *two* sockets, based on ZeroMQ, and these sockets can finally be Unix Domain Sockets which don t waste the TCP socket address space. OTOH, in well-structured environments those IPC sockets need longer path names than a simple TCP port number, additionally it might be beneficial to use Ruby techniques to build up the IN and OUT IPC sockets based on some common pattern. Furthermore, Mongrel2 relies on a uuid setting for identifying sessions.
Setting all those options on the command line to a standalone rackup execution defeats its purpose, and setting them within the config.ru file inside the tiny littly comment line is ugly and cannot make use of Ruby constructs at all. So the idea was to let the newly created Rack::Builder object handle those options and hand it over to the calling process.
My change request, together with the necessary code and test changes, was rejected and closed right away by James with the comment
> config.ru is supposed to be portable and not bound to a particular server.
I wonder whether it s James who doesn t understand what I want, or whether it s me who doesn t understand what config.ru is supposed to be. I thought it is meant as a server configuration file: It
defines which server technology to use (if there are multiple to choose from or if I want a specific solution), configures the used server, and defines which application and possible middleware to load.
The goal, as far as I got it, is to have the application and its setup bound together in a single configuration file, called config.ru. Sadly, the current syntax is only optimized for defining the application; the first two items on the list are handled via a clumsy comment line that gets longer the more options the web server requires for configuration.
So, can someone enlighten me, what s the purpose of config.ru? Isn t it supposed to carry the configuration for the web server as well? Is it a bad idea to let Rack::Builder collect all these options within the config.ru body instead of the comment line?
I think the config.ru is a interface for rack and let the rack to do something what we want .
Whatever we do anything with the config.ru, we need to based on the rack interface provided, that is why we create a file config.ru for rackup to start up the variety of web server, just my opinion.
> Recently, I forked rack and created a feature > [https://github.com/rack/rack/pull/245] that allows one to specify web > server options as commands within config.ru, not only on the rackup command > line or the comment line (#\) within config.ru. The need for this arises > from new web server technologies like the ones typically used for Mongrel2 > which need significantly more setup information than a simple Webrick or > (legacy) Mongrel server.
> Mongrel2 typically exchanges its web server requests and responses through > *two* sockets, based on ZeroMQ, and these sockets can finally be Unix Domain > Sockets which don’t waste the TCP socket address space. OTOH, in > well-structured environments those IPC sockets need longer path names than a > simple TCP port number, additionally it might be beneficial to use Ruby > techniques to build up the IN and OUT IPC sockets based on some common > pattern. Furthermore, Mongrel2 relies on a uuid setting for identifying > sessions.
> Setting all those options on the command line to a standalone rackup > execution defeats its purpose, and setting them within the config.ru file > inside the tiny littly comment line is ugly and cannot make use of Ruby > constructs at all. So the idea was to let the newly created Rack::Builder > object handle those options and hand it over to the calling process.
> My change request, together with the necessary code and test changes, was > rejected and closed right away by James with the comment
>> config.ru is supposed to be portable and not bound to a particular server.
> I wonder whether it’s James who doesn’t understand what I want, or whether > it’s me who doesn’t understand what config.ru is supposed to be. I thought > it is meant as a server configuration file: It
> • defines which server technology to use (if there are multiple to choose > from or if I want a specific solution), > • configures the used server, and > • defines which application and possible middleware to load.
> The goal, as far as I got it, is to have the application and its setup bound > together in a single configuration file, called config.ru. Sadly, the > current syntax is only optimized for defining the application; the first two > items on the list are handled via a clumsy comment line that gets longer the > more options the web server requires for configuration.
> So, can someone enlighten me, what’s the purpose of config.ru? Isn’t it > supposed to carry the configuration for the web server as well? Is it a bad > idea to let Rack::Builder collect all these options within the config.ru > body instead of the comment line?
On Oct 2, 2011, at 4:25 AM, Matthias Wächter wrote:
> Hi,
> Recently, I forked rack and created a feature [https://github.com/rack/rack/pull/245] that allows one to specify web server options as commands within config.ru, not only on the rackup command line or the comment line (#\) within config.ru. The need for this arises from new web server technologies like the ones typically used for Mongrel2 which need significantly more setup information than a simple Webrick or (legacy) Mongrel server.
Traditionally rack handler authors make the basics work using common standards (such as booting on port 9292), and then for enhanced configuration, they create their own bin file that supports extra options. See for example thin(1).
> Mongrel2 typically exchanges its web server requests and responses through *two* sockets, based on ZeroMQ, and these sockets can finally be Unix Domain Sockets which don’t waste the TCP socket address space. OTOH, in well-structured environments those IPC sockets need longer path names than a simple TCP port number, additionally it might be beneficial to use Ruby techniques to build up the IN and OUT IPC sockets based on some common pattern. Furthermore, Mongrel2 relies on a uuid setting for identifying sessions.
> Setting all those options on the command line to a standalone rackup execution defeats its purpose, and setting them within the config.ru file inside the tiny littly comment line is ugly and cannot make use of Ruby constructs at all. So the idea was to let the newly created Rack::Builder object handle those options and hand it over to the calling process.
rackup is not specificaly intended for this use case.
Rack::Builder builds rack applications, it is not a generic server configuration system (which is far more complex, as you elude to above).
The intent of the rack project is to be a middleware between servers and web frameworks/applications. rackup is provided largely as a convenience and example, and would become significantly bloated if we were to try and support configuring all servers.
> My change request, together with the necessary code and test changes, was rejected and closed right away by James with the comment
>> config.ru is supposed to be portable and not bound to a particular server.
> I wonder whether it’s James who doesn’t understand what I want, or whether it’s me who doesn’t understand what config.ru is supposed to be. I thought it is meant as a server configuration file:
I understand what you want, but I do not want to maintain it. This can be perfectly serviced by your handler code carrying a bin file containing the specific requirements for your web server configuration.
> It
> • defines which server technology to use (if there are multiple to choose from or if I want a specific solution),
This is not an intended feature of config.ru. If you add a shebang with arguments, that will only work on *some* platforms. Not all exec*(2) implementations support arguments. This approach is not portable.
> • configures the used server, and
There is no portable way to do this from inside config.ru.
> • defines which application and possible middleware to load.
This is all that config.ru is supposed to do.
> The goal, as far as I got it, is to have the application and its setup bound together in a single configuration file, called config.ru. Sadly, the current syntax is only optimized for defining the application; the first two items on the list are handled via a clumsy comment line that gets longer the more options the web server requires for configuration.
> So, can someone enlighten me, what’s the purpose of config.ru? Isn’t it supposed to carry the configuration for the web server as well? Is it a bad idea to let Rack::Builder collect all these options within the config.ru body instead of the comment line?
You should be able to run rackup(1) with a different -s flag and the config.ru will work (furthermore, if the user executes rackup(1) directly, then the shebang is entirely ignored) . Your proposal would lead to config.ru files that are not portable in this manner.
James Tucker <jftuc...@gmail.com> writes: > This is not an intended feature of config.ru. If you add a shebang > with arguments, that will only work on *some* platforms. Not all > exec*(2) implementations support arguments. This approach is not > portable.
Early rackup actually had that, it seems it got lost in the movement to rack/server (and it works nevermind whether the shebang ist parsed):
> I understand what you want, but I do not want to maintain it.
Okay, let’s try it once more. I am really sorry for my initial pull request which might have caused your dislike of the patch as it included patches for another feature. I am really willing to enhance my git skills, so bear with me.
The actual change is simple and I think that you won’t have any trouble maintaining it. Remember, it’s coming with tests! :) I haven’t filed a new pull request, so please review the two commits I made on my branch, based on the latest rack/master branch.
The changes do two things (not counting the changes for the test). First, I changed the eval() to not just return the app object – reduced from the Rack::Builder object via #to_app – but the full Rack::Builder object. As a side effect, this reduces the amount of code that runs within eval(). It allows to get the Builder object’s options to be returned and merged with the options given on the command line and on the special comment line. Second, I added the function which allows setting/adding options and retrieving them once the Builder object creation is done.
>> It >> • defines which server technology to use (if there are multiple to choose from or if I want a specific solution),
> This is not an intended feature of config.ru. If you add a shebang with arguments, that will only work on *some* platforms. Not all exec*(2) implementations support arguments. This approach is not portable.
Nonono. I refer to the comment line starting as "#\" (yes, a backslash) which carries options – parsing these options is actually the first thing done in parse_file() after reading the .ru file. My patch is all about removing the need to use this #\ special comment line and allow Ruby constructs to be used instead.
>> • configures the used server, and > There is no portable way to do this from inside config.ru.
Portable in which sense?
If I want to use rackup, I can use the #\ line or a whole lot of command line options to choose and configure the server. Why not allow those users to make those settings in a more Ruby-ish way?
>> • defines which application and possible middleware to load. > This is all that config.ru is supposed to do.
Ouch. Then please remove rackup from rack.
> You should be able to run rackup(1) with a different -s flag and the config.ru will work …
As long as only portable options are entered to config.ru, the -s flag will work, certainly. At the moment, mongrel2 is special as it requires more and different options than a standard webrick/mongrel/thin server, i.e. just a port to run from.
> (furthermore, if the user executes rackup(1) directly, then the shebang is entirely ignored)
No, as said above, I am not referring to the standard shebang line but the one with the backslash.
> . Your proposal would lead to config.ru files that are not portable in this manner.
Yes and very much no. Users who want to use rackup and who want to setup their servers inside config.ru and know the limitations of the #\ line can do that already, but it comes at the price of having only one such line, special string escaping and just supporting strings. My patch allows for a much more elegant way of specifying these options within config.ru’s Ruby part, for those who want to use this feature – maybe it will lead to rackup being much more than an example binary in the future?
Can I ask once more what’s wrong with this addition? It doesn’t hurt anyone using Rack now, and it removes the burden to write a separate binary just for calling rackup with the right options, like suggested in analogy to Thin. It is clear Ruby, no magic, no nothing.
Please, don’t ask me to maintain my own branch just for this stuff, please!