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