 Thanks, Evan, for a nice talk about community. I'm going to talk about community a little bit towards the end, but we're actually going to do a little more technical stuff in this talk. Talk about Merb. Merb is a web framework that is a little bit different from some others, taking a couple different approaches as far as being a little more modular, a little more agnostic as far as back ends go. These SQL databases have been the way to store data for a long time now, but we're seeing all kinds of new ways of storing data, CouchDB, StrokeDB, ThroughDB, SimpleDB, MIMCacheDB, all these different kind of persistence models that maybe fit a web kind of mashup situation better than a relational database. As everybody moves kind of towards cloud computing and all this stuff, Merb is kind of my experimentation ground for this. It's really good for building web services on and for not handcuffing you into a certain situation. We're going to take a quick look at some of the guiding principles that I've had with this project. It kind of grew, this project has grown out of some frustration with some other projects that will remain unnamed. Prefer simplicity over magic as much as possible. There's no need to have monuments to personal cleverness in your code if you don't need them. Simple is usually better. It scales better in the long run. People can read it later. It runs faster. Ruby opens up a huge array of features and metaprogramming techniques that you can use to accomplish goals. There are many ways to accomplish the same thing in Ruby, which is great. It's part of why I love Ruby. Just because it's there doesn't mean you have to use it as your first weapon of choice. You probably have all read recently that there's been this whole thing, monkey patching is destroying Ruby. It's not destroying Ruby, but it should not be your first weapon of choice. As the Ruby community grows, lots of people have come for the rails and stayed for the Ruby. As our community grows, there's going to be more and more code. You're going to be using other people's libraries. It's time for people to grow up a little bit and be responsible about code you write. In your own applications, your application stack, do all the gratuitous metaprogramming you want, but if you're going to write code for other people to use to build their stuff on top of, we need to be a little more responsible about what we put in our libraries because as the community keeps growing, the open classes, everything can be changed at runtime is one of the most powerful features of Ruby. It can cause a lot of problems and hard to track down things if you're not very careful with how you use it. Simplicity is better than magic 99% of the time. Having the magic when you can't get that last 1% is what makes Ruby one of my favorite language. I kind of got ahead of myself. This is framework code I'm writing here. No gratuitous use of symbol to proc or returning or any of these little things that may add, well, in some people's minds, may add a little more readability or elegance to the code. In my mind, elegant is getting things done with as little code as possible in the simplest way possible. That code will scale much further, not as far as, you know, scalability, runtime-wise, which it will, but scalability in coming back to it later and be able to understand it, having other people come back to it later and be able to understand it, and building a framework, you're building a foundation for everybody else to build their houses on top of, and you don't need a foundation that is crazy, right? So when in doubt, benchmark and profile has been a guiding principle, you know, there, you know, Ruby has a bunch of quirks, and as you use it more and more, you can kind of start to get a feel for what's expensive and what's not, but in reality, you're almost always going to be wrong about what the bottleneck is in a certain piece of code, you know, to a certain extent. So benchmarking and profiling is really the only way to know for sure what a problem area is. And know your runtime and how it acts. Ruby is a complex animal, and learning its, all its different variables and all the different ways that it behaves will really benefit you in the long run. It's very easy to fall into the trap of saying, oh, look how expressive this is, look how can we do this, we can dynamically define these methods and generate all this code at run time, and that's a great thing to be able to do, especially in experimental programming and stuff, but as the Ruby community scales, I implore library writers to keep this kind of stuff in mind. There's a bunch of different stuff we can talk about as far as Ruby performance quirks, you know, like methods defined with defined method rather than a normal def or three times slower to call, you know, I already said, symbol to proc is slow, there's just a bunch of idioms that may take one line out of your code, one or two lines, and you may think is elegant, but there's different ways to think about elegant, right, there's this look so elegant, there's also this run so elegant, right? No code is ever going to be faster than no code, right? So keep it simple, right? This is a good model to live by, no need to just generate volumes and volumes of code when a few lines will do. I get asked a lot of times why I built another web framework when we all have, when we have Rails and we have this, you know, this great thing with Rails, why fracture the community, why, why, why, because I wanted to, why not, right? It's fun, it started as a hack and it just got fun and I've been working on it for a few years now, almost, well, a year and a half at least, and it's been a fun experiment. Rails was so pioneering and has so many awesome ideas in it that I just really love and it has some things in it that I really loathe and that's fine and Rails is an awesome platform and, you know, I still fully support it but I just, you know, it was a little too opinionated for me and I had some differences of opinion and, you know, Rails is like nothing can beat it for the 80-20 rule, at least for the 80 part of that rule, right? You can get up and running and get an application done faster in Rails than you can in Merb and you can make it that first 80% and if you're building an app that 80% is all you're ever going to need, then please don't use Merb, go with Rails because it's going to get you there faster but when you, you know, as the web advances and there's all this world of service-oriented architecture and REST and web services and mashups and all this kind of stuff, there's, you know, and hosting all the hundreds of applications we hosted at Ingenyard, I see all these pain points when people are trying to push that last 20% and they have to fight against the framework. So Merb is kind of written in a way where it gets out of your way. It might not be as, you know, rad, you know, rapid application development-wise so it might take you a little, you know, a couple of extra days to set up when you're getting started or whatever but it's going to scale you better later as far as when you wanted to do something that it was not intended to do, you know, that I haven't thought of yet or, you know, that's not part of the framework because the whole idea of the code in Merb is to get out of your way and allow you to cherry-pick features you need rather than say, here it is, like it or leave, you know, like it or leave it or fight with it if you have to leave the golden path. So we hear this a lot, right? Developer time is expensive, servers are cheap. So who cares if, you know, there's always been a meme, oh, Rails doesn't scale. Well, I can tell you firsthand that Rails completely does scale. I've seen it, you know, numerous times and time again. It just doesn't do so efficiently so you're going to pay for it on the back end, which, you know, is a valid trade-off. So, you know, who cares about efficiency? Just throw more servers at the problem. We won't, you know, you get your application done quicker but, you know, applications have to run for a long time. So throwing servers at the problem only goes so far, right? And, of course, I'm happy to sell you more servers. But you hear this a lot, too. Premature optimization is the root of all evil, blah, blah, blah. Well, post-mature optimization is the root of all hosting bells. Okay? So trust me on that one. Okay, let's get back to Merb. So what's new in Merb? It's been around for like a year and a half. It's grown pretty organically over that time and started to get a lot more people actually using it around the end of last year and kind of took a step back and looked at it and said, okay, now it's not a hack anymore. People are really going to be using it for production applications. Let's take a step back, tear this thing down to its roots and build it back up again the way it should be. Let's get rid of any remaining things I don't like in there and let's clean it all up, make it really what it's supposed to be. So Yehuda and I spent like January and February completely taking it apart, putting it back together in a pretty modular fashion. So we've split it up into a Merb core gem, which is basically your HTTP abstraction, your controllers and views rendering, your bootloader for determining the load order of the framework, your server tools and your web service like REST type implementation and routing. And that's the small core. You can get an app going and start using it with just core and you can go a long ways with that. And then we have Merb more, which is a whole bunch more gems for different functionality, caching, Hamel, all kinds of different stuff. So the idea is you start with core, which is only, you know, which is the small package and if you start a new app and you boot it up on core, it only uses like 12 megs of RAM. So you can write these really tiny fast web services for when you need to, you know, throw something up here and have it back in for your Rails app or throw something up there to proxy in between S3 and your download so you can authenticate and still stream right through Merb from S3 to your client. We've rebuilt the framework on top of Rack. Like Merb originally stood for Mongrel and ERB when it was first a little hack and I had really tight integration with Mongrel for streaming and a number of other things. And that served us very well. But now that it's become a framework all on its own right and people are using it in all kinds of different situations, we standardize on Rack. And Rack is a web server abstraction layer. Basically it distills a web request down into a method or an object or a proc that has a call method and takes an environment hash, which is like your basic CGI hash of all the different headers and the post body and stuff coming into the request and you return an array, which is the status, the hash of the headers and the body that responds to each. So it distills a web application down into basically a proc, a callable object. And if you adhere to this interface, you can run on basically any web server available to Ruby. Right now we have adapters for ERB, evented Mongrel, fast CGI, Mongrel, Thin, WebRick, there's a light speed one in the works. So we can now run on any of these web servers, including CGI as well, but that's a little slow loading the whole framework every time. But this gives us a nice way to be able to run on any kind of setup you could ever imagine. And there's different advantages. There's been a lot of blogging and stuff lately about Thin and Ebb, which are these event driven web servers that are really fast. But there's there's trade offs, right? So Mongrel has been like the staple, stable way to run Rails applications. And it pretty much is still the winner. Overall, right, Mongrel is a threaded web server. So every request that comes in spawns a new thread, accepts the socket, sets things up dispatches to Rails, right? So Mongrel wins when you have varying response times in your application, like if you have some long pages, you know, more than two, three, four, five seconds, or you're making blocking calls to other web services. Other threads can still kind of be scheduled and you can still accept new connections and run. Whereas with the event driven web servers, ebb event in Mongrel and Thin, they are much faster. Since they don't have the overhead of threading their event driven servers, they're much faster as long as all of your requests are very short. So if you have like a web service or an application that's never going to have requests more than a second or two long, then you're going to get much better performance on an event driven web server. But as soon as you have variable length requests, or you're doing long blocking calls, the event driven servers are going to fall on their face because one blocking call can block the event loop, which means no other sockets get accepted, no other connections can be processed. So there's a big trade off. So it's nice to be able to support any of these models for different applications. Some applications can really get a lot of, you know, advantage out of using an event driven server. But in general, Mongrel is still like the best option for a general purpose application. Building Merb on top of Rack has given us some really interesting possibilities. In every Merb application you generate, there is a config rack.rb file. And this is what comes in the default rack.rb file. Run Merb Rapp application new. So this is just the default. It just runs your Merb application in a standard way. But having this config file, Rack has a no sense, Rack has distilled a web request down to a call method that takes an environment and returns an array of the status headers and body. It also has an idea of middleware and running multiple applications in the same process. So you can create middleware that would do like, you know, do logging or like wrap your call into your application in a profiler or whatever. And you can stack this middleware so that as a request comes in, it will go through the stack and do various things. So for example, you know, this is our standard Merb application doing nothing extra except for just dispatching Merb. Let's take a look at something else. So say we have, you know, say we have an application that's a standard Merb app, does a bunch of web stuff and everything, but you also have an API, like say your Twitter, and you have an API that's doing 80% of your traffic, and it's, you know, it's just a simple call that's returning XML or JSON or whatever. It's, there's no reason to go through the whole routing, instantiating controllers, dispatching through a whole framework. If you're not, if you don't need all the filters and you don't need views and all that kind of stuff, you're just returning some data, you can get a, you can get away with a much faster way of doing it. So let's break this down a little bit. This is a simple API handler. So we put this in our, in our rack.rb file. And basically this, it takes, in initialize it takes an app, which is our Merb rack application and stores it away. And it has its own call where it's taking the environment in. So it's going to take the environment in. And then the way rack middleware works is down here at the bottom we can say, use API handler, run Merb rack application new. What that's going to do is it's going to create a stack by calling initialize on the API handler and passing in the application we're running to store it away. And then it's going to insert itself in front of every request. So when a request comes in, this, this API handler is going to get called. We're going to instantiate a new Merb request object so we can get access to params or anything else we would want. And then we're going to check if the request path matches API as a simple example. And we're going to capture whatever comes after API. And if it does match, we get a request in. We're going to, here's our, here's our array that we return. We've got status 200 for yes, this request is okay. We've got a hash of headers, content type equals text JSON. And then we can call like into our API model, you know, this is a very simplified version, call into our API model, get the JSON from the regex match and return that as the body. And so on every request, we can short circuit the whole framework by checking if it's an API call and returning just JSON right away. And like you can't get much faster than that in Ruby. There's really like a very low overhead to this. Now if the request doesn't match, we're going to just fall back and call our Merb application. And it's going to go ahead and go through the whole framework and dispatch your controllers and your views and everything. So this is really powerful. I don't know if anybody's ever written custom mongrel handlers for the Rails application where they mount them in front to be able to handle different things. Well, this is very similar. It's stuff we'll work across any web server or setup you're using. And there's a lot of different stuff you can do with this. There's also there's a bunch of middleware that comes with rack. There's like a common logger. It's pretty exception screen. There is a cascade, which means you say, okay, here's a new cascade and you pass it in an array of rack applications and say, try all these applications and the first one that returns a non-404, we're going to render that. So by having this available, you know, to put in front of your Merb application, you can just have so much flexibility. And if you don't need Merb at all, I'd highly suggest everybody check out rack and build yourself a simple little one feature website on it or something. It's really, really cool and it's really easy to make an application. Just define a proc or a class that has a call method, takes the environment and returns an array. It can't get much simpler than that. So that's the power of rack. Merb also has a really powerful router. It can do full restful stuff, very similar to Rails, nested resources. And you can see here, this bottom part is like the exception detail screen where you can view like all your named routes and everything. So it can do most of the stuff, 95% of the restful routing stuff that Rails does in a similar way, but it also has some much more powerful features where we can basically dispatch based on anything in the request object, the user agent, subdomains, the host name, anything you could think of. Here we're using the user agent. So in the first route, the request comes into foo slash whatever and this route will only match if the user agent is Microsoft Internet Explorer or Gekko, otherwise it's going to fail. And in the hash here you can see title has this little bracket one. That will be replaced with the match from the regex. And then we have the user agent is basically a match data object. So there's really powerful ways to take a request and pull it apart and route based on anything. This bottom example is an example of deferred routes, which means instead of just checking if it matches, we can insert some arbitrary logic. So here we'll say if you match bar with a placeholder after it, defer to this block and the block takes the request object and the params hash from the incoming request and you can do anything you want in here. So in your router you could call into the database and say, you know, if we can find by this parameter, we'll return a hash. So Merb's router, when a route matches, it returns a hash that has the controller to instantiate the action to call and any other parameters that could come in in the params hash. So here we're basically deferring this route and changing the way it works based on some call out of the database. We could easily do like, you know, check the subdomain, look it up in the database and tell it which controller to route to or whatever based on that. So with a deferred route, you either return a hash of controller actions and any other params or you return nil or false and that route won't match and it will continue on to the next and the next and the next and try it going from there. So it just gives you a lot more power over how your application is going to match up to request coming in. So another really cool feature is the provides API. I really didn't like how, I mean I really like the idea of Rails RESTful web service interface, you know, write these respond to blocks, you know, respond to wants XML, wants HTML and be able to serve different content types based on the accept header or the format or whatever. That's like a really powerful idea, but I just hate how ugly the respond to blocks are and it just seemed like, I just didn't seem like a nicest API. So we've done something a little different in Merb. By default, all controllers provide HTML, but in this little example, we are going to also provide JSON, YAML and XML and it might be a little hard to see, but up at the top we've got Merb's MIME types and we're going to say, you know, we're going to say Merb out of MIME type for YAML, we're going to give it a symbol of the method to call on an object to get YAML from that object, so to YAML and then we're going to say here's the accept headers where when a request comes in that says I accept text YAML or application X YAML, then that's what's going to match. So we've set these up for YAML, HTML, XML and JSON. These ones are built into the framework, but you could easily set up your own foobar MIME type with a two foobar method. And then in this show method here, this is one other feature of Merb that's pretty cool is you can write your methods like normal Ruby methods. You don't have to depend on a magic params hash. The params hash is there, but if you define your method to take arguments on the dispatch on the way through Merb, it's going to say, oh, this show method has an ID, right? So I'm going to look up the ID out of the parameters and pass it in as a normal method argument rather than making you play with this magic params hash. Params hash is still available, but I find this like to be much more Ruby-ish. So show takes an ID, finds a post and then we say display post, right? So based on what the accept header coming in is, when you call display, say we request XML. When you say display post, what's going to happen is it's going to determine what the request wanted as far as a MIME type, and it's going to call the two whatever method on that. So it's going to call, you say we request XML, it's going to reply by calling two XML on the post object and returning that value. So and if there is no, and there's all, you know, if there's a template on disk, the template will override. So if there's like an HTML template or whatever, that will override you have templates for different content types. But doing it this way, there's also a normal render method, but display is pretty useful. It falls back to render and it gives you this way to abstract what you're displaying to the client. So not only could we do this with just the two XML on like an active record object or a data mapper object, but if you wanted to get into like the idea of a presenter where instead of using a template, you want to have an object that takes a number of child objects and figures out how to display them itself, you could have a presenter object and say, you know, find a post and put it in at sign post, find a comment and put an outside comment, and then say, you know, display presenter new and passing the post in the comment and then two XML or two whatever will get called on the presenter which can decide how to display those objects it contains. So it just gives us much more leeway in the future to change the way we want to display objects or how we want to handle that. I don't have code in there yet, but I am working on a canvas style renderer where instead of using actual templates, you use objects that know how to build themselves and display as HTML or XML or whatever. So that will be coming pretty soon, but this just leaves us really flexible way of doing things. And so Merb actions are much more like Ruby methods than an action in Rails. They can take arguments from the parameters and whatever they return is going to go back to the client. So there's no auto rendering. You always have to call display or render or something because the return value of the method is what's going to go to the client. And this opens up a lot more flexibility as well. You can just, you know, you don't have to use Merb's rendering or display or anything. You can just return a string that you built from whatever and that will get sent back to the client. Or you can return an open IO handle like you can open an IO object or a file or whatever. And if you return an open IO handle, Merb will see that and it will stream it to the client as a file. Or if you return a PROC object, Merb will see that and it will say, oh, this isn't a string or a file. It's a PROC. So I'm going to call that PROC and pass in the response stream as an argument so that I can, you know, drop a PROC out of this method. And in that PROC I can like write to the response anyway I want, streaming-wise, do loops over whatever and write chunks out to the client. So this opens up all kinds of flexibility. Like one of the use cases for this, being able to return a PROC is say you, you know, say you have S3 files that are private, that are password protected and you want to be able to stream them down to your user, what you need to authenticate in your Merb app first and you don't want to show them the S3 URL. So you could have a request come in, you could open a connection to S3 and inside of a PROC that you return from your, from your action, you can start reading a chunk from S3 and writing it to the response right away and have a loop that goes over and does that so that a request comes into Merb for a certain S3 object. Merb authenticates, make sure the user can see that object and then it opens a stream from S3 and reads a chunk and as soon as it reads a chunk it writes a chunk right to the client so it's like a proxy in the middle and it doesn't have to like download the whole thing into a buffer and then download to the client again. So Merb is all about services and being a man in the middle or whatever, it just is really flexible for dealing with the web in general. Quickly, in Merb More there's a bunch of code generators, there's a asset bundling with callbacks so you can say, you know, when I first boot the application server I want you to go and grab all my JavaScript files, compile them into one file and call out to JS men or YUI men advisor or whatever and pack those into one file and then return that. There's mailers and parts which Merb has an abstract controller type which doesn't know anything about the web but it knows how to do before filters and after filters and how to render and use like the provides API and all that kind of stuff. So that gave us a lot of fixability, Merb web controllers that you use on the web, you know, take the request and the response and they set up the session and the prams and they know all about the web and all this stuff. Parts are kind of like components done right. They behave exactly the same as your other Merb controllers, you write them the same, they have their own before and after filters, they can have layouts, their own views, their own whole directory but they aren't directly callable from the web, they're callable from other controllers or views. So you can encapsulate little components, you know, little applets of your site in a full controller with filters and layouts and templates and everything and then call that from a view or from a web controller to build your application in a more modular way. And so those are just a subclass of Merb's abstract controller type. Same thing with mailers. The mailers are just another controller type. In Rails, mailers are like what are they? Are they a controller? Why do they live in the models directory? Who knows, right? But it's much more consistent here. Mailers are just another type of controller. They have templates. You can add attachments, render views and shoot them out and it just makes you so then your mailers can have layouts, filters, all that kind of good stuff. We support Hamel as a first class citizen so you can use Hamel and ERB and you can intermix the two and have partials that are Hamel that call ERB partials or whatever. Merb takes a different approach to how it handles templates. When you boot the server, it runs through all the templates in your application, has the template engine parse those into Ruby code, the intermediate step and then it installs those as methods in an inline template module. So your templates get fully compiled and turned into a method so when you render, basically all it has to do is figure out which template you were thinking of and then call that method. So there's no, so rendering is really, really fast and partials are basically just method calls instead of a whole check on the disk and blah, blah, blah, all this stuff. It basically turns all your templates into methods which has a huge performance advantage. Merb or more also has the action args plug in which is the way of letting you pass in arguments to your actions and that's actually pretty cool. It uses parse tree and Ruby to Ruby to like inspect all of your controllers on the server boots and figure out what the actions are and what arguments they take and how to pass that stuff in and assemble it together. We've got a nice caching plug in and all the other essentials and this stuff is all opt in. You can start building an app with just core and then as you need pieces you add a piece here, add a piece there or you could just say require Merb more and get it all at once and we also have Merb plug ins which has typos I guess. Dartemapper, that's a new one. Anyway, so Merb officially supports three different ORMs, Datamapper, ActiveRecord and SQL and there's a plug in for each one of these. You can tell it to use which ORM you want to use and it knows how to do migrations for each one and how to integrate those into the application and load them properly and everything. So it gives you flexibility to choose what you want. My personal preference is Datamapper. It's an awesome project. I know Yehud is going to be speaking about it a little later today and he can tell you more about that but if you have a Rails application and you're having performance issues with it and you need to create maybe a little web service or a little component part of your Rails application written in Merb and you have all ActiveRecord objects you can actually build a Merb app and since the framework is so modular you can, in the configuration options you can say, here's my Merb app everything lives in here except the models directory is actually the models directory of my Rails app. So, did you have a question? Yeah, so pull that in instead and load those models and go from there. So most Rails plugins that deal with ActiveRecord will work fine in Merb. Plugins that deal with Action Pack or a little iffy you might have to port or whatever. Yeah, so we've got a helpers plugin with a bunch of form helpers and all that kind of stuff and there's a lot more being worked on. So, if you want to contribute to Merb or just like play around a little bit it's up on GitHub. Please go fork the project and play with it. We've been really enjoying using Git as our and GitHub is an awesome project to get involved with and using it as our way of source control it brings a whole new a whole new way of working with a project like this. As people want to make a new feature they can go on GitHub and click fork and get their own fork of Merb and go ahead and make their feature whatever it is and then they can send me a pull request they can say, here are my features finished here's a pull request and the next time I log into GitHub I'll say, oh hey, so and so sent you a pull request with this feature added and I can just say, oh, get pull and I'll pull in his feature into my main repo and it's really cool because it fosters experimentation. It's not one some version repository that most people don't have commit rights to or whatever and it's really, you know, subversion is really branches are just ugly they're hard to merge it's just a it's not a it's not a conducive thing to experimentation because if you want to really take somebody's you know, take a take Merb or Rails or whatever and do some drastic drastic changes with if you're doing it from their subversion repository you can't commit incrementally and you can't commit your changes you have to make this monolithic code fist patch, right? and shove it up their maintainers, whatever and that's no fun, right? This is great, have you actually do you have any statistics or even anecdotal evidence that this is encouraging people to contribute in a way that it doesn't in the centralized repo? Yes, I would definitely think so there's like 60 or 70 forks of Merb on GitHub right now and a number, you know I've gotten a great bunch of features from a number of different people and there's been stuff that I didn't like and they've still maintained their own fork of that and so that really it really fosters experimentation because people can make a fork do something maybe crazy or maybe different and if it doesn't make it back into mainline they can still easily maintain their fork with the features and still pull from mainline much easier than they could do with subversion probably everybody that works with Rails has their own private not really a fork but like their own patches that they put on every project because these things they want are not in core and they can't get them in or it's just too much of a hassle so everybody's got their own little privately maintained edge case stuff and if you were working in Git instead of subversion you could maintain your own fork and still commit to it still pull from the main repo it just opens up for a much more I don't know it's just a much more conducive environment for experimentation so I just wanted to say you said earlier that Merb takes a little longer to set up and that's definitely true today but it's definitely our mission to make Merb as easy to set up as Rails we just value things like being able to be modular and hackability at this particular point of time over trying to guess what the correct default is right so as Merb gets more mature it becomes more obvious what the right defaults are so the mission is to have a similar experience to Rails where we have a thin layer on top of Merb all the defaults that people can use right and then you can just take that off or override pieces instead of having to basically monkey patch what already is there so our goal is to have a really modular system that is that allows to make it really easy to add defaults and so it will be really easy to set up with that like I said it's just not the case today I want to introduce you to Rails is doing a great thing and they're moving to get shortly, sometime next month which I really applaud and I think that's a vast move forward for them because it's going to really level the playing field it's not going to the core team won't be as much of a monolithic thing anymore because anybody could have their own fork with their own features and it kind of promotes the survival of the fittest thing if somebody's got a cooler branch some people use it or if somebody's got a branch with features that somebody needs for a certain application they can use that it just it kind of like if it's an open source project to begin with distributed version control I think is a much higher level way of working with the community because it allows people to go off on their own tangents and still be able to commit incrementally and the merging and the branching and stuff is just so much easier What would it be worth it to run an event that's sort of like an event in Mongrel for most actions and then spin off the slower approach to all Mongrels? Possibly, it kind of depends on the situation, right? Well, so if you have if your application is like 90% really fast actions you could like run those on Thin or Event in Mongrel or Ebb Ebb is like really fast and then you could run your slow actions on Mongrel, right? And then in your InginX or whatever your front server is you can say, okay any of these URLs to start with, slash, slow will go to the Mongrels and the other stuff anything else will go to the Thins or whatever Yeah, that's what you were showing Well, yeah, you can't I mean, you can only well, that's not true if you really wanted to you could fire up multiple servers in the same process on Okay, the question was what was the question? The question was could you run like an event driven server for certain actions and Mongrel for other actions that are slower? And the answer is yes with Rack it's all just adapters and servers and with Merb the way Merb has all these different modules built in for web servers you could actually in the same process start a Mongrel for your application on port 3000 and start a Thin or an Ebb on port 3001 and you would still have to have something up in front like Nginx or whatever to say, okay, these requests go to this one and these requests go to that one but they could still be in the same process With your company, do you have any large clients that are using Merb? Yeah, we have quite a few people that are using Merb a lot of people are using it like in conjunction with the Rails applications for pulling out their web services or their file uploads or something we have a number of applications that are about to launch that are all fully on Merb and there's a number of actually really large companies that I'm not allowed to really say their names that are using it for some performance intensive stuff a lot of web service stuff and that's where it really shines I'm not trying to be as fully as full of a stack as Rails is I like Merb to be more of a experimentation playground for new persistence back-ins new ideas of having web services all that kind of stuff but adoption is rapidly picking up Talk earlier on about keeping things really tight and just do you have to use for profiling when you find that you're saving because you're in the middle of the lake and there's nothing around it? RubyCoff is pretty much the best profiler for maths is Ruby if you're running on Rubinius Rubinius has a really nice built-in sampling profiler that doesn't affect performance at all your code runs at full speed but you get samples of what's going on you know the debuggers RubyDebug helps but yeah basically so there's a couple different ways of doing it there's profiling setting up a profiling action and Merb has a built-in underscore underscore profile underscore underscore method that you can give a block of code to run and say run this a hundred times or a thousand times and show me everything that takes more than point one percent of the time and so you could wrap this around all the calls to your application and have it print out an HTML graph of where the performance critical places are also I do a lot of stuff where okay I'm writing I've got this idiom here where I'm using inject or I'm using this or that or the other so I'll break out a little piece of functionality and say okay I can do this these five different ways and then I'll write a benchmark for each one and see which one is faster or has features I want or whatever and in the Merb source there's a simple benchmarks directory that has like a bunch of uh... little a bunch of those little files where I compare different ways of doing things and decide which one's better memory profiling uh... bleak house works pretty well you have to like it has a custom ruby interpreter that's implemented the the memory and garbage collector to get a bunch more stats out of it that works pretty well uh... there's a really good article from the guys at pluron they did a bunch of profiling of rails applications and found a bunch of little things that were affecting memory and they have a good write-up of that i will uh... I'll post my slides to my blog at brain splat later today and include some links for this kind of stuff for you uh... so we have uh... for controller and we have uh... create method right standard restful controller the old way of doing it would be too can you guys not see that okay the question was can you explain a little bit more about how the uh... parameter passing for arguments that are merb actions works so the old standard way of doing it would be you know create and you'd say you know posts or whatever foo dot create params foo right and foo would be a hash of whatever the attributes of that object are uh... the way merb action args works is instead of writing that you can write create foo uh... foo and then instead of having to use the params hash you just what happens in during the dispatch of the of the merb application setting up your controller it will know that your create method takes a foo parameter and it will look in the params for a foo key like you have up here for params foo and it will pull that out and pass in basically params foo as the foo argument to your method so it's not it's kind of just a little syntax sugar it just kind of cleans things up a little bit allows you to you know pass in all this kind of stuff so you could have an action you know that takes uh... an id and a name and the id could be have a default of forty two and the name could have a default of gerald or whatever then instead of having to pull you know having to do all these hash lookups and pull the stuff out of the params hash all the time you can just say oh well this method takes these arguments and can have defaults and as part of the dispatch merb will know that your action takes these parameters and will fill them in from the request that's a good question so what was the question? The question is how did it know? it's a little bit complex like it uses a library called Ruby parse tree in Ruby to Ruby so when the server boots as your controller classes are loaded each one of them gets run through parse tree so it gets turned into the abstract syntax tree which is basically like a lisp looking s expression the abstract view of your code which is what Matt's Ruby interpreter takes all of your code parses it into this sex p they call it and then it walks around this tree executing the code so in that using the parse tree gem you can say give me the parse tree for this method and it will give you this nested array with symbols and stuff in it and you can say okay I want the arguments node out of this array and so I can know that this method takes a foo parameter with this default and takes a bar parameter with this default and then I store those away in a hash and as part of the dispatch when it comes in I know okay for this control foo controller for this create method it takes these arguments so put those in from the parameters from the request instead of instead of not it's all done in bootstrap so there's no noticeable overhead of this it's all like at bootstrap it does this thing compiles you know gets the sex p gets the parameters memoizes them away in a hash that just gets used as a lookup during the dispatch so there's no performance hit for it do you have development mode so for this type of thing it also pretend it's so you change them while the server is running do you know how to do this? yeah we've got a whole in development mode we've got a code reloader that for every file that gets loaded it takes a note okay fine it says okay object constants here's the constants in the program right now and then it loads a file and then it stores away which constants that file loaded so that later when that file in time changes on disk and it can before it reloads a file again it goes through and removes all those constants that it knows this file is going to create and then it reloads a file again and for templates in development mode it will recompile the template on each call or if it's changed so if you're using parse-tree to do the argument stuff is parse-tree a compile check? yes it is so if you found it at constant problems would it actually be sort of doing that thing? not really I mean it's a it's an opt-in feature it's not in core it's in more so you can not use it if you don't want to but there are we worked with a couple people and there is now pre-compiled windows binaries of parse-tree and Ruby inline and Ruby to Ruby that was the main thing is like people on windows were like you know crying because they don't usually have compilers and it was a pain in the butt for them so I'm sorry can you say that again? doesn't that mean you can't breathe or more in your application? no that doesn't mean that because the uh the compiled stuff doesn't actually live in the gym it's part of it's part of parse-tree and Ruby to Ruby so as long as you can get those gyms installed it doesn't actually have to compile anything on the fly uh it's just they use Ruby inline to make it easier so it is a pre-compiled thing you can you could freeze parse-tree and Ruby to Ruby into your application but that's not super advisable if you're gonna put it on different platforms you'd be better off just installing those native gyms on the platform first or if it's really a pain in the butt just not using it the action art is really cool they really like that but in my mind that falls slightly on the side of magic how do you decide where to draw the line between simplicity and magic? usefulness versus if you're not going to really use it that's why it's not in core right it's in more which is an opt-in thing so it's not a core feature but it's something that I've found in writing applications it just fits better with my brain so yes it is a little bit of magic that's probably the most magic part of MIRB but uh since it's an opt-in thing and I get a lot of uh I get a lot of joy out of it I kind of turn I kind of turn my head on that one I guess right so it's magical it makes it it makes it more like just normal Ruby rather than these magic brands that appear like finding a method that takes a lot of stress and it kind of fits in with how much is this returning value instead of automatically rendering you can also use those from other methods right if you come in on one you can call another method in the controller exactly without having to push it in the prance hash and then pass it along yeah so it makes them just more like normal methods basically how do you benchmark them and test them? how do you use them both? we're 99% just straight mongrel because it is the better one-size-fits-all solution but we do have maybe 20 or so customers running on thin and it's a trade-off it's the classic event driven versus threaded networking server deal the thin is really fast faster a little bit faster than event in mongrel and ebb is even faster yet ebb is based on LibEV it's really fast all written in C and all of ebb is written in C except for the very thin layer that dispatches to rack to your Ruby application so ebb is like smoking fast for short requests but both ebb and thin kind of fall in their face as soon as you have intermixed long requests in there so while they are really cool and I like the projects a lot I can't recommend them as just a full-out replacement for mongrel because they're not they have different trade-offs I've small tested both of them my model was with ebb and just pure C and I think at least on my little edge it wasn't as stable as thin and a lot of people in the thin list were going to say well if it's more Ruby you can play more with and with just pure C it takes a whole different level to interact with that's true it's the classic trade-off for speed in Ruby C extension versus pure Ruby and ebb is still very young I wouldn't recommend anybody use it in production yet it's still very new and it's gotten better but it was kind of unstable and stuff but I mean the C is all kind of hidden just for the web server part since it exposes a rack interface which thin does as well you're still able to do most of everything in Ruby as far as putting together and composing different applications and handlers and stuff but yeah it's like there is no panacea these new event-driven web servers are not going to cure everybody's problems and make everything so much faster especially for almost all applications I see in the wild have some requests that take two or three or ten seconds you know they have a report file uploads or yeah I mean threaded mongrel beats all the other ones hands down for file uploads because it can still accept new connections while the files are being processed whereas with an event-driven server you know as soon as the it can do all the networking without blocking but as soon as it locks up rails or whatever and you're doing the processing of the file the whole time you're doing that processing of the file the other connections are able to be processed so the throughput of those event-driven servers just like drops like this when there's long requests in the application so you have to make the trade-off and what Tim said earlier is a good idea like if you have you know if you know that 90% of your application has really fast response times it could greatly benefit from an event-driven web server maybe you know at your front end proxy server you split off requests and send fast requests you know for certain URLs to the fast servers and you send the other slower file uploads and stuff to your threaded mongrel basically if you can separate my URL and you can do it and take the best of it exactly exactly yeah so you're kind of hidden you're almost to kind of a 1.0 type of release so you're stabilizing how much where do you really see a going after this it depends like I you know we just released 0.9.2 to Rubyforge which is the first release we've actually put on Rubyforge of the whole complete new refactored codebase so I'm going to let that gel for a while and I want to see a bunch of new applications written and launched before we'll go 1.0 1.0 is still a little ways out because I want it to be very polished and I want it to you know I want to get a bunch more applications using it in the wild and figuring out if we're missing anything or if we need to take something away so you know 1.0 is a pretty big stake in the sand for an open source project and I want it to be as perfect as possible the direction that goes after that we'll see you know I kind of have the I kind of above the opinion that I don't after 1.0 is out it's going to be pretty much kind of feature complete anything else that needs to happen can be a plug-in since the whole thing is built very modular so I don't foresee it just continuing on and adding and adding features and adding features I'd rather see it become a community of you know modular features that people can add or remove as they need and doesn't have you know not everything the framework doesn't have to do everything it's nice when it does and when your application kind of fits that mold it's a great thing to have you know the framework do everything for you but as applications get more complex and people you know glom together more web services and are building these these crazy things a lot of that stuff has to be in the application code it's so application specific that bloating up a framework with features to support all these edge cases is not what I want to do I just want to see if it has an option do you thread a request processing yes it does I haven't got to play with it much yet to see whether it kind of negates the benefit of having the event-driven server or not spawning a thread for each request but yeah that's there's also another thing I've been playing with for when you run Merb on evented mongrel event machine has this thing called deferrables where you can stop processing a request and like defer some processing to later so that the event loop can run again so I've been playing with continuations which probably aren't the best solution and deferrables to be able to say okay here I've got this Merb action that's doing all these complex stuff that takes a lot of time so in between each step I can like yield so that the event loop can run again and serve more requests and come back and continue processing my stuff later but that's all really experimental right now Yeah, so he said you went to the website and there is no like build a blog in 5 minute thing and yeah we were that's another big thing that we're going to do before we release 1.0 is like copious documentation and tutorials and stuff that's kind of what we're going to do before we release 1.0 is like copious documentation and tutorials and stuff that's kind of what like Merb is stabilized now to the point where there's not a lot left to be done there's just a lot of trial and vetting by fire so I'm going to be focusing on more tutorials and stuff and we're actually writing a book for Manning on Merb that will be coming out pretty soon but yeah that's some that's a place where there's a Merb IRC channel that's really active and really helpful if you wanted to jump in there we'd be happy to like get you up and running and go through some stuff and if anybody wants to feel like writing some documentation that would be great along that lines I wanted to mention another thing that I forgot to put in the presentation that I think is pretty cool about the way we're doing Merb and that's our documentation and API standards we've come up with a documentation format that's you know states what all the parameters are and their types and the return types and what a method can do and whether and we've made a distinction between public API semi-public API and private APIs and this is so in our specs for Merb Core we have private specs and public specs and public specs are APIs that are contract with my users that we will not change and that we'll try as hard as we can to not break but the private API stuff is private and that allows me to work through the way the framework works or drastically change the underlying techniques without as long as I don't break the public API so I think that's a really kind of cool way of documenting a framework and but yeah I agree we need more tutorials and Merb is just kind of settled down now where I feel it's a stable platform for everybody to start building on so I'm sure there will be more forthcoming I think I'm going to have to wrap it up here everybody's probably been surprised by now so thank you