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
[email protected]
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel