On 28 Jul 2010, at 20:03, Joshua Ballanco wrote:

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

Hi Joshua,
Thanks for pointing that out. For some reason I had missed CT coming with Rack, 
so had assumed otherwise. I've just tested omitting that in my code and it 
works like a charm.


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

Great, I have amended my code to reflect the correct API. Incidentally I have 
had great success in getting concurrency working with MacRuby HEAD (0.7) for 
serving up my XML feeds and the raw files.

I also notice you're explicitly requiring 'rack/handler/control_tower.rb'. Is 
that going to remain the case too? Or could this be folded into the main 
require 'control_tower' call, if you're going to indicate that this is good 
practice.

Lastly, I just wanted to check with you on threading. I'm wrapping that whole 
sequence above in a simple method, and using the following to spin it out from 
the main thread:

@webserverThread = NSThread.alloc.initWithTarget self, 
selector:'startServerThread', object:nil
@webserverThread.start

But I found myself needing to create an autorelease pool (as I would with 
writing obj-c) at the beginning of #startServerThread otherwise I saw some 
really funky corruption and crashes.  Now I'm a little fuzzy on how GC works, 
so is this a necessary requirement when spawning new threads within a GC run 
environment?

Nick

_______________________________________________
MacRuby-devel mailing list
MacRuby-devel@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Reply via email to