I am starting work on a new project soon and was wondering whether to create multiple apps (pretty much copies of each other) or one single app (or utilize single sign on of some sort). Each 'app' will have its own domain.
The apps are pretty simple, people can sign up to the site and create a profile for their cat or dog. However, as some people have a cat and a dog, it would be nice to not have them sign up twice. Also, I think many users will want to extend to other pets too, such as rabbits, rats, ferrets, etc
It will be a Rails app, and so I wondered what my options are.
A single app would be easiest to maintain
Multiple apps could mean it is easier to 'split' the network i.e sell some of it (tho I doubt I'd do that)
But which would be most efficient? Would there be any problems with caching? Which makes most sense?
If you have any links or info on how to go about your preferred method, that would be appreciated too! But at this stage, I am mainly asking about which is the most logical way to go about it.
Less is always more, especially early on in a project.
I've learned to never split code bases until it's absolutely apparent that it must be done.
Making 2 apps means twice as much work in so many ways. Two bundle exec rails server to run, two bundle exec rspec to run, cd .., cd web_app1, cd web_app2 over and over.
You also have to deploy two apps.
So, make one app. Split it up later, if and when you need to.
If they are on the same subdomain, you can share cookies, and easily achieve SSO.
And there is no reason you can't use something like nginx to put them behind their entirely separate domains, as a deployment consideration.
If you were planning to have multiple domains with a separate application on each domain, you could have a "central" domain (or server) that can hold all shared resources (images, css, javascript, data etc) and provides the ability to load-balance and increase performance. It can be a lot of work connecting everything and keeping it all running so it depends on your situation.
Related
I want to build an application that would handle CRM, client database, time tracking etc.
The app would be sold to about 100 clients. The thing is that every one of clients will have slightly different needs i.e. they want to integrate app with their own accounting software or have added functionality only for them and in their instance, they want only those modules, that they are using.
I'll need to manage 100 different instances of the same app, so I want it to be easy. For example if I'd fix a bug for one instance I want it to be easy to propagate this bugfix to all other instances and if I create a module for one client I want to easily add it to another client's instance if he would want to.
What is the best way to do this in this situation?
I would be really thankful if someone would point me to the right direction ;)
Generally this is handled by making things data-driven. Everybody gets the same code, but with different feature-flags which enable/disable various bits of the application.
Feature flags can be driven in a database, config files, environment variables, etc depending on your needs.
I have a few questions on appropriate folder structure in cucumber:
I think I am going to organize my feature folders according to type_of_user/type_of_feature.feature, i.e. main_admin/add_a_customer.feature or franchisee/schedule_job.feature. The only slight issue with this is that of the user types I have: cleaners, customers, franchisees and main admin/franchisor, the latter two users share many features. For example, both franchisees and franchisor have the ability to add new customers and schedule jobs, the only difference being that the franchisor has the ability to schedule a job for anyone, anywhere - i.e. the only real difference is permissions, not functionality. Does it matter that I will be essentially duplicating tests for these two users, given the proposed folder structure? Or should I be looking to seperate folders by functionality only, then type of user?
For my mobile app, should I have these feature folders separate from the web app or should these go in the root as well: mobile/ios/cleaner_login.feature, mobile/android/cleaner_login.feature etc?
Regarding user types:
Organizing at the top level by user type has worked well for me. However, I would only consider user types separate if they actually used different features, not just if they differed in permissions with respect to specific objects as in the example you gave. You could consider both franchisees and franchisors "administrators", make a top-level folder for those, and just write scenarios for franchisees and franchisors for features that had different permissions for those roles.
If you're a developer and writing RSpec specs in addition to Cucumber features, you might even just write specs instead of features to cover the difference between franchisees and franchisors. (I would only do that if the differences between franchisee and franchisor were fairly trivial and not worth exposing in Cucumber.) If you're QA and testing only from the outside of course it'll all have to be in Cucumber.
I would certainly not systematically duplicate entire scenarios for the sake of any organization. The extra work required to maintain the duplication and the errors when you forgot would be far worse than the bit of extra work required to follow a slightly more complicated system that minimizes duplication!
Regarding web and mobile: How to handle different platforms depends on how different they are.
If you have a web app and a native (Android, iOS) mobile app the step implementations will be completely different and your tests will need to be in different projects altogether. That probably won't mean that much duplication, since the users and features in the web and mobile apps will probably be rather different.
If you have two web apps, one for desktop and one for mobile, there are no technology issues. But again it will depend on how similar the two apps are. If they're different, separate them at the top level (even before users). If they're very similar, separate them only when necessary and only at the scenario level.
I have a RoR app that is installed multiple times in the same machine. The app is the same, it's just installed with different names (i.e: app1, app2, ...).
The app uses ThinkingSphinx for searching. It has one index for the model Element. Each installation of the app will have it's own database with its own Elements.
So my question is:
Should I have multiple Sphinx instances running by changing the port, one per app? (I tried this option with 2 installations and it works well, but I think there are some issues regarding server load)
Should I have only one Sphinx instance? In that case, where should I configure Sphinx? How can I configure it to access different databases? How can I tell it to differentiate between instances from different apps?
Should I go with another solution?
Thank you in advance
Separate Sphinx instances (running on different ports) is definitely the way to go.
Sphinx requires every document to have a unique id, even between different index files, so managing that with a standard Thinking Sphinx-generated configuration is painful with multiple applications - you'd need to manage the single configuration file yourself, really, plus adapt Thinking Sphinx to only search across the relevant data set for each app. It could be interesting on some level, but my gut feel is that it's really not worth the effort or time. Use different ports, different daemons, much easier.
I'm in the early stages of prototyping a Rails 3 application that will expose a public API. The site has three separate concerns which I am planning to split across three subdomains.
api.mysite.com
The publicly exposed API.
admin.mysite.com
The admin portal for creating blogs (using the public API).
x.mysite.com
The public blog site created at admin.mysite.com where x is the name of the blog. This too will make use of the public API.
All three will share domain objects. For example, you should be able to login to admin.mysite.com using an account you created on api.mysite.com or x.mysite.com.
Questions
Should I attempt to build one rails application to handle all three concerns or should I split this in multiple applications each handling a specific concern?
What are the Pros & Cons of each?
Does anyone have any insight into how some of the larger sites (basecamp, github, shopify) are organized?
Your question is fairly general so I'll try and answer in general terms. And the fact that you mention "larger sites" leads me to the conclusion that you're concerned about scaling.
In the beginning it is definitely going to be easier to build one application - especially since the domain is shared. You can do separate controllers for the various interfaces (api, html, etc) but with a shared back-end. This will reduce code duplication and the complexity of keeping 3 apps in sync. Also remember that you might change your mind about features based on user feedback and you want to be nimble enough to respond quickly.
The main benefit I can see of separating out three different deployables is that you can have an independent deploy schedule for each. For example, a bug fix in the api won't have to wait for admin to be ready to deploy. Or that you can have separate teams working in parallel.
If you're careful about what you keep in your session you'll be able to deploy multiple instances of your application on multiple servers, pointing at the same database (a.k.a. horizontal scaling). Each of these instances are identical to the others and a load balancer (either dedicated hardware or virtual) directs traffic between them. Eventually this approach runs out of steam when your database can't handle the load. At that point you can look at more caching, sharding, no-sql and all sorts of clever scaling techniques.
Most (but not all) larger sites end up doing some sort of horizontal scaling with some sharding of data.
All told, focus on getting a useful application to your users. If things take off you can worry about scaling. More applications fail because the user experience is awful rather than not being able to scale.
We have a very lage Rails app that has two distinct sections: the front end and the CMS/Admin. We would like to break up the app into two pieces (for maintenance, as we have distinct teams that work on the front end vs. back end and they could have different release cycles).
One thought was to start a new Admin 2.0 app that has access to the models/schema from the original application, but has its own controllers/views and its own models that extend the original models until it is safe to fully decouple. Is this advisable? If not, what would be an appropriate plan to migrate away from one monolithic codebase?
warning, this is a bit ranty, and does not go anywhere.
Having worked on a very large app that operates in the manor you describe (for scalability reasons), I still have mixed opinions (an no conclusive answers).
Currently we operate 3 major apps (+ one or two smaller ones that use a fragment of the schema).
RVW (our admin app): This is the only app that writes, runs on a single server, and is responsible for maintaining the schema.
reevoo.com: ecommerce, price comparison, stuff like that. This (for historic reasons runs on a slightly different schema, run on a read only slave of RVW, with database views to map the schemas. All writes are done by sticking things on queues that RVW picks up and acts on. This works very well, although the number of random db related issues (mostly related to the views) is an issue. The main problem with this app is the difficulty sharing code (gems work well, I've often dreamed of bringing the schemas into line and sharing the core models in a gem!). We share code between apps using ruby gems. And test using lots of integration tests that cross app boundaries (using drunit (presentation on this available)).
reevoomark: very high load b2b app. This has many servers each with a full stack (db server, app server one per node). These have their databases populated with a db export - import batch job. This works very well in the short term, the shear flexibility of it is just ace, but integration testing between apps is very hard.
My advice would be to avoid splitting the apps at all costs, keeping things DRY quickly becomes a major challenge. My advice would be to stick with one app, two sets of routes (selected at startup by environment variables).
This gives you all the advantages of the other solutions, while making code sharing implicit. Splitting your test packs out would make your test cycles shorter and make things more manageable for the two teams. I would avoid working on different code bases, as doing this promotes the apps drifting apart and making code sharing tricky (as in .com).
If you decide do split, have a good set of high level cross app tests. Custom (per app) extensions to a core set of models sounds like a good plan, although with distinct code bases and teams you may still end up with duplicate code. Rails engines should be a good way of sharing the models, but be prepared for model reloading to become a little schizophrenic.
Good luck!
Have you namespaced your admin controllers? That would be a relatively easy point of subdivision and also avoid many of the negative side effects of forking your code into two apps.
Have you considered looking at Rails Engines? Added to Rails in 2.3.