[MacRuby-devel] ControlTower in MacRuby

Joshua Ballanco joshua.ballanco at apple.com
Wed Jul 28 12:03:23 PDT 2010


Apologies for being so late to reply...

On Jul 21, 2010, at 11:44 AM, Nick Ludlam wrote:

> On 21 Jul 2010, at 15:31, Alexander von Below wrote:
> 
> Hi Alexander,
> I've got a MacRuby app happily running very happily with Control Tower. First I cloned the code from github, and built and installed the macgem package. Then I also installed rack with
> 
> sudo macgem install rack

ControlTower currently has a version of rack that is vendored into the gem. Currently it's the same as rack v1.2.1, but with one particularly annoying bug fixed (unrelated to Ruby vs. MacRuby). Originally we made rack a gem dependency, but we decided that vendoring might work better for now, since there may still be MacRuby specific bugs lurking. There's also the possibility that we could optimize parts of rack for MacRuby, though there's nothing like that in there now. I'll do my best to keep the vendored version up to date with the latest rack release.

tl;dr -- You shouldn't have to install rack to use ControlTower, but there's not any harm if you do.

> in order to get some of Rack's built in server functionality. Then a short script would look like:
> 
> 
> require 'rubygems'
> require 'control_tower'
> require 'rack/utils'
> 
> server_options = { :port => 3001, :host => '0.0.0.0', :concurrent => false }
> 
> app = Rack::Builder.new do
>  map "/" do run Rack::File.new("/Users/nick/Sites/") end
> end.to_app
> 
> @s = ControlTower::Server.new(app, server_options)
> if @s
>  puts 'Starting control tower webserver'
>  @s.start
> else
>  puts "ERROR: Couldnt build server"
> end

This will work...however...

There are two ways to use a Rack based server to run a web app (this is true for more than just ControlTower):

1. Use a rack-up file (e.g. config.ru) and pass it as an argument to the server start script (or, in the case of thin, if you're running a Rails app thin is nice enough to go find the file for you). The contents of this file are then eval'd in the context of Rack::Builder.new

2. Programmatically, create the app (as above) using Rack::Builder.new and pass it into one of the rack handlers. If you look at the standard rack distribution, you'll see that there are handlers for all of the common rack servers. Eventually, we should submit a pull request for rack to include our handler, but for the time being ours is located in the control_tower gem. So, the example above would look like:

-----
require 'rubygems'
require 'control_tower'
require 'rack/utils'
require 'rack/handler/control_tower'

server_options = { :port => 3001, :host => '0.0.0.0', :concurrent => false }

app = Rack::Builder.new do
 map "/" do run Rack::File.new("/Users/nick/Sites/") end
end.to_app

Rack::Handler::ControlTower.run(app, server_options) do |s|
  puts "ERROR: Couldnt build server" unless s
end
-----

The reason to use the handler, instead of calling Server.new directly (even though, that's pretty much all the handler does), is that this is part of the rack-protocol, and guaranteed not to change. At some point in the future, we might add some more complicated logic around how to start a server, at which point your code that directly calls Server.new might break.

Cheers,

Josh


More information about the MacRuby-devel mailing list