 This was my project for Ruby Summer of Code, and I must say that Ruby Summer of Code is one of the greatest things that can happen to any programmer. I learned really a lot. I worked with really experienced people that taught me a lot. I don't know if you recognize this guy. He is Carl Huda. Some people say that actually Carl Huda are two people, but that's just from our teaching. No, but seriously, I discussed with them the entire idea, and they worked on Rails, so they prepared the stuff. I didn't need to rewrite the entire Rails. I just worked over the APIs that they prepared, and just the volume was my secondary mentor, but he spent countless hours on helping me and discussing things, reviewing my commits. Yeah, very good. He very much helped me. And thanks to sponsors, because it could happen only because so many sponsors responded, but raised so much money for that. And getting back to multiple applications, I can say that multiple applications are applications that can be mounted in some other applications. So let's start with a short story. Let's say that your client comes in and he says that he needs a blog, and it needs to be integrated with your application. And users should be able to comment using their existing profiles, and you should be able to display some posts from that blog on the main page of the application, and you say that you can just write it in 15 minutes, because writing is about writing blogs in 15 minutes, but I would say that it will take a bit longer, probably, because you would have to write tests and maybe some comments moderation for file uploads, or other things that you would probably need. And maybe you could use existing blog software like Moffisto or Daigo or something like that, but if it needs to be integrated, you will run into problems, because you will have to somehow synchronize users Daigo, for example, or I don't know, use two databases or merge it. This will probably cause some problems. And you should ask yourself, is the blog covered business, or is it just an addition that maybe you could just take generic blog and mount it inside your application and don't care if it has all the features that you want. Maybe you can just stick with some generic software. And there are, of course, more examples that can be used as multiple applications, like CMS, for example, static pages, or forum, or file manager, or any other things like that. And it's nice, but how can you use it in a race? And I would ask if you are there, if you can use it now. And I can say that, yes, we can use it, but at the same time, I can say that it's not done as you would expect probably, because our goal was to run two race applications in one process. And unfortunately, it's hard. For example, if two applications needs to set values for some config values, you must choose which applications should win. Or if you have some billboards like session billboards or something like that, it should be run only once. So you would have to somehow say that some billboards should run only on the host application. And for example, if you load one application, how do you know if it's only a dependency, and other application will load it afterwards? Or is it a host application? And we don't know if it's really needed, because we could probably solve the problems, but if you think about that, when you need to do multiple applications, you would have to probably do some design decisions that are entirely different from standard application. So choosing only one way is much easier, and you probably should do that way rather than trying to do both. So how can we do it now? We can use engines, and probably you would think that using engines is not a good thing, because we have it from race to point one, I think, and these are plugins with controllers, right? Before we start our code, engines were a bit more powerful plugins, and right now in race 3.1, race will be almost as powerful as applications. So the only difference would be that you can't run engine standalone, you must mount it into other applications, but that's not an issue for me. So I extended engines by adding routes to engines, they now can have their own routes, middleware stack, so engines can now be run application, and they have plugins support, so you can add plugins just like in normal application. And of course there are new APIs that can handle communicating between engines. So these things are only available at edge version of race, so if you want to play with it, you should just clone it from GitHub, and the most important thing is mounting an engine. So here I just mount the block engine at slash block, so all the controllers from that engine are now available at slash block address. And the second important thing is that now you can isolate engine. So what do I mean by isolate? If you have, for example, engine like device, it's an authentication system, it should be shared with application because it is just an addition to application, but if you have something like block or forum, it should probably be treated as separate application and not share, for example, helpers and routes and stuff like that. So if you try to build a mounted application, you should use isolated engine, and we can isolate engine inside some namespace. So here I set isolate namespace block, and now the engine is isolated inside that namespace. And we need namespace for two reasons, because we want to avoid conflict if you have two comments model. Models, for example, in block and CMS, mounted applications. Without namespace, they will conflict and you will get nowhere. And the second thing is that we need to recognize if object belongs to engine. So here we have block post model, and we know that this instance variable post is from block engine. We can check it and we can do further things with it. So I will tell now about a couple of effects of isolation, and the first one is that in race 2, or even in race 3.0, if you had a controller, even if it was namespaced, it got all the application helpers. So you couldn't do something like isolated controller that will get only helpers from some namespace. And with isolated engine, you just have it. It has only routes from the engine, and it will have only helpers from the engine, from the namespace block. The second thing is that when controllers are namespaced, you normally would have to scope all the things inside routes. And with isolated engine, you don't have to do it, it is done automatically, so you don't have to write the code that is connected. And the next thing is avoiding the prefix, because it will be fine to write through the entire application to write block underscore something. So in shared engine, if you have block post, you will end up with names like block underscore post title, and you will have to use params block underscore post. And in isolated engine, we know that all the models and controllers are prefixes with that block underscore, so we can skip it, because we know how to do it. The same with paths. Normally, you would have to write block underscore post path, and in the isolated engine, you can write this post path, so it's much easier to do that. You don't have to write prefixes everywhere. And also with generators, know about namespaces. When you generate model, for example, in isolated engine, it will generate model inside namespace, and will automatically create migration with namespace table, so we don't have conflicts in database. And the next thing that is very important is a route, because if you have isolated application, it will have its own router, so here we have controller block post controller, so it's controller from our block engine. And if you want to use post path, we can do it like we normally do in regular application, but we can also call route from host application or some other engine by saying here main app dot root path, so it will get path from application router. And here the same, this is controller from application, and we can use route path as normally we would do, but if you want to get some route from engine, we can do block dot post path, and it will get route to our post path from block engine. And we can of course change it. We can say the model block engine has shiny block, and we could do now shiny block dot post path, so you can change it if it conflicts with something else or you just don't like the name or something. And chances are that you will need static assets, so you can do it in two ways. You can use config dot serve static assets, that will serve static assets by action dispatch starting, or you can copy assets to applications by doing create block install assets. You can do the same thing with migrations. You can do rate block install migrations, and you can copy all the migrations to applications directory, and you can do both things by saying create block install. And as you now know APIs, you probably wonder how to create an engine, and you can do it by saying race plug in U, give the name of the engine, and pass minus minus on table, and minus minus ejection. And I don't know if it's in current now, because as I said that human manager, but I don't really know if he does it already, so if it isn't on GitHub, it will be probably tomorrow, and after doing that, you can just, for example, generate scaffold post and run the server, and it will behave just like normal application. Just mounted some graphics, and I said that it's not possible to run engines standalone, so you need some application to run it inside, and it's done by creating dummy application test dummy. So when you use things like script-trade-server or script-trades-console, you just use the dummy application and the engine is mounted inside. And my work is pretty much finished, but we will need to battle-test the APIs, so if you are interested in the topic, you can just grab it from GitHub and try it. And I would like to be able to set some standards, like authentication and authorization, if we will use standards like, for example, we have now current user for almost all authentication systems, and if you would have similar APIs for other things, the chance is that if you take two mountable applications and mount it in other applications, and it will just work, it will be much bigger. And I would like to have some feedback, so if you have some complaints or if something doesn't work as you would expect, just message me on Twitter or on GitHub, and drop us on Twitter so you can follow me or message me or something, so we can talk about mountable applications or whatever else. That's all, thank you. You can go as long as you want. Do you want to take some questions? Yeah, so when you want to do questions, I don't think so. The engine that you need, which has its own database, will you be able to separate those databases? So when you do mountable applications, the question was about if you have an engine and it has a separate database, if an application has separate databases, what can you do? So if you develop a mountable application as an engine, the easiest way would be to just use one database. So if you use ActiveRecord, and mountable application is also ActiveRecord, all the tables will be namespaced, will be prefixed with, for example, block understore prefix, so the best way is to just run with one database. And if, for example, mountable application needs something like Mongo or your application needs like MySQL or something, you probably will not, you probably can't do it. If it's something that is completely separate and it doesn't need any tables from host application, it could work, but if you, for example, need to share user's table, it should be one database and one, probably one ORM, or maybe even two ORMs, but they should have one convention of tables. The last comment you made, let's say you share user model and you're relying on the hosting app to have some sort of user object. Is there a place where you can put an adapter? How do you handle that? Actually, it's her question, because I haven't done much engines because I haven't had time after creating these APIs, but probably the, because I said that designing application to be both standalone and mountable will be hard and this is one of the reasons that in standalone application you should have user model and in mountable you should use, you should use user model from host application and I think that the best way to do it is just some engines that I saw that did it already do it like either checking if there's user model and using it or making it easy to configure it so we just pass class name of whatever would be user model like for example device is straight engine it is not isolated application but it uses, you can just say what would be something, what would be the user model so I think that it would be the best way to just have some API to tell that our user model is this and maybe create some hooks so you can for example give code back to authenticate or to authorize something but it should be that way does that answer your question? yeah so thank you thank you