SlideShare une entreprise Scribd logo
1  sur  86
Télécharger pour lire hors ligne
From 1 To 30
         How To Disassemble
One Monster App Into An Ecosystem Of 30

            Beta 技术沙龙
              http://club.blogbeta.com
              官方twitter : @betasalon
Groups : http:// groups.google.com/group/betasalon

           Jonathan Palley, CTO/COO
             Guo Lei, Chief Architect


                   © 2010 Idapted, Ltd.
An
Experience
A Tale of Two Buildings
2009 Shanghai
                 Lotus Riverside Community




1909 Beijing
Forbidden City
1


30
What is one?
The entire web
   application/system/platform
     runs as one single rails
            application

(We are talking about really large systems.
Multiple different types of clients/functions)
Problems


Confused new staff




                     Hard to test/extend/scale
What is 30?
A ecosystem of applications
Independent
Linked and Seamless
Basic features of each app
•   Separate database
•   Runs independently (complete story)
•   Lightweight (single developer)
•   Tight internal cohesion and loose external coupling


                   Advantages
• Independent Development Cycle
• Developer autonomy
• Technology (im)maturity safety

          APPEAL TO DEVELOPER LAZINESS
What’s the mystery of the forbidden city?
Consistent UI
• Shared CSS/JS/Styleguide
• Common Helpers in Shared Gem
• Safely try new things
interface
      All applications use the same base CSS/JS


   Keep all the application the same style
   <%= idp_include_js_css %>
   # =>
   <script src ="/assets/javascripts/frame.js" type="text/javascript"></script>
   <link href="/assets/stylesheets/frame.css" media="screen" rel="stylesheet"
       type="text/css" />
interface

            CSS Framework
interface

   Abstract Common Helpers to Gem
   Search function for models
interface
        Common Helpers: Combo search
                  (cont)
   View:
   <%=
   search_form_for(HistoryRecord, :interaction_id, :released,[:rating,
   {:collection=>assess_ratings}],[:mark_spot_num,{:range=>true}],
   [:created_at, {:ampm=>true}])
   %>

   Controller:
   @history_records = HistoryRecord.combo_search(params)
interface

            Common Helpers: List table




well formatted        sortable
with pagination       customizable
interface

   Common Helpers: List table (cont)
   <%=
    idp_table_for(@history_records,:sortable=>true,:customize =>
   "history_records") do |item, col|
     col.add :id, link_to(item.id, admin_history_record_path(item)),:order=>:id
     col.build :duration, :waiting_time, :review_time
     col.add :scenario, item.scenario_title, :order => :scenario_title
     col.add :mark_spot_num
    end
   %>
interface

            Development Lifecycle
  1. Implement new View code/plugin in a
     second application
  2. Abstract into plugin using existing
     “idp” helpers
  3. Put it into main view gem
interface   data
data


How do applications share data?
 (remember: each app has its own data)

 -“Read Only” Database Connections
 - Services
 - AJAX Loaded View Segments
data
         Business example

                     user

                             purchase
       course

          learning process
data
                Purchase App

   Requirement: List course packages for
         user to select to purchase

                        but
   The course package data is stored in the “course”
                      application
data
                    Solution

       readonly db connection




           course
data
                               Code

 Model:
 class CoursePackage < ActiveRecord::Base
    acts_as_readonly :course
 end

 View:
 <ul>
 <% CoursePackage.all.each do |package| %>
   <li><%= package.title %> <%= package.price %></li>
 <% end %>
 </ul>
data

    Why doesn’t this break the rule of
           loose coupling?
 Model:
 class CoursePackage < ActiveRecord::Base
    acts_as_readonly :course
 end

 View:
 <ul>
 <% CoursePackage.all.each do |package| %>
   <li><%= package.title %> <%= package.price %></li>
 <% end %>
 </ul>
data

       acts_as_readonly in Depth

 def acts_as_readonly(name, options = {})
   config = CoreService.app(name).database
   establish_connection config[Rails.env]
   set_table_name(self.connection.current_database +
   (options[:table_name]||table_name).to_s)
 end
data

        acts_as_readonly in Depth

 def acts_as_readonly(name, options = {})

   config = CoreService.app(name).database
   establish_connection config[Rails.env]
   set_table_name(self.connection.current_database +
   (options[:table_name]||table_name).to_s)
 end
data

                    Core service

 class CoreService < ActiveResource::Base
     self.site = :user
     def self.app(app_name)
         CoreService.find(app_name)
     end
 end
data

       Centralized configuration

How does Core know all the configurations?
data


Each app posts its configuration to core
  when it is started
data

 config/site_config.yml
       app: course
       api:
         course_list: package/courses

 config/initializers/idp_initializer.rb

       CoreService.reset_config
data


 core_service.rb in idp_lib
       APP_CONFIG =
         YAML.load(Rails.root.join(“config/site_config.yml”))

       def reset_config
          self.post(:reset_config, :app => {
             :name => APP_CONFIG["app"],
             :settings => APP_CONFIG,
             :database => YAML.load_file(
                          Rails.root.join("config/database.yml"))})
       end
data




       Model in Purchase:
       class CoursePackage < ActiveRecord::Base
          acts_as_readonly :course
       end
data



       Again, implemented in gem

   config/environment.rb

   config.gem ‘idp_helpers’
   config.gem ‘idp_lib’
data




       gems
data




• Web services for “write” interactions

 class CoursePackageService < ActiveSupport::Base
    self.site = :course
 end
data
                 example

       Roadmap needs to be generated
        after learner pays.
data
                           codes
 Course: app/controllers/roadmap_services_controller.rb
 def create
    Roadmap.generate(params[:user_id], params[:course_id])
 end
 Purchase: app/models/roadmap_service.rb
 class RoadmapService < ActiveSupport::Base
    self.site = :course
 end
 Purchase: app/models/order.rb
 def activate_roadmap
    RoadmapService.create(self.user_id, self.course_id)
 end
data
                AJAX Loaded Composite View
<div>
<%= ajax_load(url_of(:course, :course_list)) %>
</div>
                     Ecosystem
                       url_for




              Fetched from
                different
              applications
data

              Open Source



   http://github.com/idapted/eco_apps
interface   data   user
user
       Features of User Service

 • Registration/login
 • Profile management
 • Role Based Access Control
user
                 Access Control
 Each Controller is one Node




       * Posted to user service when app starts
user
                  Access Control
before_filter :check_access_right

def check_access_right
     unless xml_request? or inner_request?
       access_denied unless has_page_right?(params[:controller])
     end
end




 * Design your apps so access control can be by controller!
user




       How to share?
user
       Step 1: User Auth

              SSO

             Shared
             Session


           Same Session
              Store
user
                  Step 1: User Auth
config/initializers/idp_initializer.rb

ActionController::Base.session_store = :active_record_store
ActiveRecord::SessionStore::Session.acts_as_remote :user,
  :readonly => false
user
             Step 2: Access Control
Tell core its controllers structure
CoreService. reset_rights

def self.reset_rights
     data = load_controller_structure
    self.post(:reset_rights, :data => data)
end
user
            Step 2: Access Control
before_filter :check_access_right

def check_access_right
     unless xml_request? or inner_request?
       access_denied unless has_page_right?(params[:controller])
     end
end
user
       Step 2: Access Control


         has_page_right?

       Readonly db conn again
user
             Step 2: Access Control
class IdpRoleRight < ActiveRecord::Base
    acts_as_readonly :user, :table_name => "role_rights"
end


def has_page_right?(page)
    roles = current_user.roles
    roles_of_page = IdpRoleRight.all(:conditions => ["path = ?",
  page]).map(&:role_id)
    (roles - (roles - roles_of_page)).size > 0
end
user
          Again, gems!

  config/environment.rb

  config.gem ‘idp_helpers’
  config.gem ‘idp_lib’
  config.gem ‘idp_core’
interface   data   user   service
service

            Support applications

          • File
          • Mail
          • Comet service
File
Specify Class that
                     class Article < ActiveRecord::Base
    Has Files         has_files
                     end

 Upload File in
 Background to       Idp_file_form
  FileService


   Store with
  app_name,
 model_name,
   model_id

 Use readonly
 magic to easily     @article.files.first.url
    display
service

                               Comet
  class ChatRoom < ActiveRecord::Base
   acts_as_realtime
  end


          <%= realtime_for(@chat_room, current_user.login) %>


                       <%= realtime_data(dom_id, :add, :top) %>


                                  @chat_room.realtime_channel.broadcast
                                  (“hi world", current_user.login)
service

                        mail

  Mail services
  MailService.send(“test@idapted.com”, :welcome,
  :user => “test”)
Host all in one domain
Load each rails app into a subdir, we
  use Unicorn
  unicorn_rails --path /user
  unicorn_rails --path /studycenter
  unicorn_rails --path /scenario
Host all in one domain
use Nginx as a reverse proxy
 location /user {
    proxy_pass http://rails_app_user;
  }

  location /studycenter {
    proxy_pass http://rails_app_studycenter;
  }
Host all in one domain
All you see is a uniform URL

   www.eqenglish.com/user
   www.eqenglish.com/studycenter
   www.eqenglish.com/scenario
Pair-deploy
How to split one into many?
By Story
   Each App is one group of similar features.

By Data
   Each App writes to the same data
Example

•   User Management
•   Course package
•   Purchase
•   Learning process
•   …
Iteration
Be adventurous at the beginning.
Split one into as many as you think
  is sensitive
Then you may find

• Some applications interact with each other
  frequently.
• Lots of messy and low efficiency code to deal
  with interacting.
Merge them into one.
Measurement

• Critical and core task of single app should
  not call services of others.
• One doesn’t need to know much about
  others’ business to do one task (or develop).
• Independent Stories
Pitfalls

• Applications need to be on the
  same intranet.
• No “right place” for certain cases.
Results: Higher Productivity


-Faster build to deploy
-More developer autonomy
-Safer
- Scalable
-Easier to “jump in”
- Greater Happiness
Support Tech
• FreeSWITCH
    • VoIP
    • http://www.freeswitch.org.cn
• Flex
• Erlang
    • concurrent tasks
• Titanium
    • mobile
Full Stack of Us



CTO          Rails/Flex


 VoIP     UI     UE       System
Full Stack of Us
Develop environment:
  • 4 mbp + 4 black apples + 1 linux
  • textmate & netbeans

Servers:
  • test: 2 physical pc with Xen serving 10
    virtual servers
  • production: 2 (China) + 5(US)
Full Stack of Us
Web Server:
  • nginx + unicorn


Rails:
  • Rails version 2.3.4
  • Ruby version: 1.8.7
Full Stack of Us
Plugins:
  •   exception_notification
  •   will_paginate
  •   in_place_editor_plus
  •   acts_as_list
  •   open_flash_chart
  •   Spawn + workling
Full Stack of Us
Gems:
  • rspec
  • factory_girl
  • thinking-sphinx
DB:
  • mysql
Cache:
  • memcache
Full Stack of Us
Test:
  • rspec + factory_girl
  • Autospec


Deploy:
  • webistrano
Full Stack of Us
Team Build:
  •   board
  •   code review
  •   tea break
  •   retreat
Join Us
If you are:
  •   smart
  •   creative
  •   willing to do great things with great people
  •   happen to know JS/Flex/Rails


Send whatever can prove your ability to:
    tech-team-jobs@idapted.com
Thank you!

          Q&A
http://developer.idapted.com

jpalley@idapted.com (@jpalley)
guolei@idapted.com (@fiyuer)

           © 2010 Idapted, Ltd.

Contenu connexe

Tendances

Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...SPTechCon
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsCarol McDonald
 
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Atlassian
 
springmvc-150923124312-lva1-app6892
springmvc-150923124312-lva1-app6892springmvc-150923124312-lva1-app6892
springmvc-150923124312-lva1-app6892Tuna Tore
 
Lecture 11. Microsoft mobile services
Lecture 11. Microsoft mobile servicesLecture 11. Microsoft mobile services
Lecture 11. Microsoft mobile servicesMaksym Davydov
 
Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5Tuna Tore
 
CQ Provisionning & Authoring
CQ Provisionning & AuthoringCQ Provisionning & Authoring
CQ Provisionning & AuthoringGabriel Walt
 
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Arun Gupta
 
Mule esb
Mule esbMule esb
Mule esbKhan625
 
Java Web Programming [3/9] : Servlet Advanced
Java Web Programming [3/9] : Servlet AdvancedJava Web Programming [3/9] : Servlet Advanced
Java Web Programming [3/9] : Servlet AdvancedIMC Institute
 
Integrating Plone with E-Commerce and Relationship Management: A Case Study i...
Integrating Plone with E-Commerce and Relationship Management: A Case Study i...Integrating Plone with E-Commerce and Relationship Management: A Case Study i...
Integrating Plone with E-Commerce and Relationship Management: A Case Study i...David Glick
 
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010Arun Gupta
 
Angular presentation
Angular presentationAngular presentation
Angular presentationMatus Szabo
 
Introduction to Backbone.js for Rails developers
Introduction to Backbone.js for Rails developersIntroduction to Backbone.js for Rails developers
Introduction to Backbone.js for Rails developersAoteaStudios
 
Lecture 10 - Java Server Faces (JSF)
Lecture 10 - Java Server Faces (JSF)Lecture 10 - Java Server Faces (JSF)
Lecture 10 - Java Server Faces (JSF)Fahad Golra
 
Templates
TemplatesTemplates
Templatessoon
 

Tendances (20)

Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.js
 
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
 
springmvc-150923124312-lva1-app6892
springmvc-150923124312-lva1-app6892springmvc-150923124312-lva1-app6892
springmvc-150923124312-lva1-app6892
 
Lecture 11. Microsoft mobile services
Lecture 11. Microsoft mobile servicesLecture 11. Microsoft mobile services
Lecture 11. Microsoft mobile services
 
Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5
 
CQ Provisionning & Authoring
CQ Provisionning & AuthoringCQ Provisionning & Authoring
CQ Provisionning & Authoring
 
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
 
Mule esb
Mule esbMule esb
Mule esb
 
Java Web Programming [3/9] : Servlet Advanced
Java Web Programming [3/9] : Servlet AdvancedJava Web Programming [3/9] : Servlet Advanced
Java Web Programming [3/9] : Servlet Advanced
 
Spring MVC
Spring MVCSpring MVC
Spring MVC
 
Integrating Plone with E-Commerce and Relationship Management: A Case Study i...
Integrating Plone with E-Commerce and Relationship Management: A Case Study i...Integrating Plone with E-Commerce and Relationship Management: A Case Study i...
Integrating Plone with E-Commerce and Relationship Management: A Case Study i...
 
Oracle ADF 11g Tutorial
Oracle ADF 11g TutorialOracle ADF 11g Tutorial
Oracle ADF 11g Tutorial
 
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
 
Angular presentation
Angular presentationAngular presentation
Angular presentation
 
Introduction to Backbone.js for Rails developers
Introduction to Backbone.js for Rails developersIntroduction to Backbone.js for Rails developers
Introduction to Backbone.js for Rails developers
 
Chapter 5
Chapter 5Chapter 5
Chapter 5
 
实战Ecos
实战Ecos实战Ecos
实战Ecos
 
Lecture 10 - Java Server Faces (JSF)
Lecture 10 - Java Server Faces (JSF)Lecture 10 - Java Server Faces (JSF)
Lecture 10 - Java Server Faces (JSF)
 
Templates
TemplatesTemplates
Templates
 

En vedette

Discovery Streaming
Discovery StreamingDiscovery Streaming
Discovery Streamingrbl4
 
Itunes u presentation fnl
Itunes u presentation fnlItunes u presentation fnl
Itunes u presentation fnlrbl4
 
Migration Tips & Tricks
Migration Tips & TricksMigration Tips & Tricks
Migration Tips & TricksLaura England
 
KGIC Youth Bridge Progam PPP
KGIC Youth Bridge Progam PPPKGIC Youth Bridge Progam PPP
KGIC Youth Bridge Progam PPPkgictaiwan
 
PeríMetre I àRea
PeríMetre I àReaPeríMetre I àRea
PeríMetre I àRearfenollosa
 
Vivim A Catalunya Ii
Vivim A Catalunya IiVivim A Catalunya Ii
Vivim A Catalunya Iirfenollosa
 
2008 Kgic Summer Camp Pic Up The Mic
2008 Kgic Summer Camp Pic Up The Mic2008 Kgic Summer Camp Pic Up The Mic
2008 Kgic Summer Camp Pic Up The Mickgictaiwan
 
Endocrine Pathology
Endocrine PathologyEndocrine Pathology
Endocrine Pathologyknickfan18
 
Breast Histology
Breast HistologyBreast Histology
Breast Histologyknickfan18
 
Lotame Animated Presentation
Lotame Animated PresentationLotame Animated Presentation
Lotame Animated Presentationlotame
 

En vedette (18)

Discovery Streaming
Discovery StreamingDiscovery Streaming
Discovery Streaming
 
Itunes u presentation fnl
Itunes u presentation fnlItunes u presentation fnl
Itunes u presentation fnl
 
British Legacy
British LegacyBritish Legacy
British Legacy
 
Migration Tips & Tricks
Migration Tips & TricksMigration Tips & Tricks
Migration Tips & Tricks
 
Images Chap10hahn8e
Images Chap10hahn8eImages Chap10hahn8e
Images Chap10hahn8e
 
Images Chap08hahn8e
Images Chap08hahn8eImages Chap08hahn8e
Images Chap08hahn8e
 
Images Chap06hahn8e
Images Chap06hahn8eImages Chap06hahn8e
Images Chap06hahn8e
 
KGIC Youth Bridge Progam PPP
KGIC Youth Bridge Progam PPPKGIC Youth Bridge Progam PPP
KGIC Youth Bridge Progam PPP
 
PeríMetre I àRea
PeríMetre I àReaPeríMetre I àRea
PeríMetre I àRea
 
Resum
ResumResum
Resum
 
S Terciari
S TerciariS Terciari
S Terciari
 
Images Chap14hahn8e
Images Chap14hahn8eImages Chap14hahn8e
Images Chap14hahn8e
 
S Primari
S PrimariS Primari
S Primari
 
Vivim A Catalunya Ii
Vivim A Catalunya IiVivim A Catalunya Ii
Vivim A Catalunya Ii
 
2008 Kgic Summer Camp Pic Up The Mic
2008 Kgic Summer Camp Pic Up The Mic2008 Kgic Summer Camp Pic Up The Mic
2008 Kgic Summer Camp Pic Up The Mic
 
Endocrine Pathology
Endocrine PathologyEndocrine Pathology
Endocrine Pathology
 
Breast Histology
Breast HistologyBreast Histology
Breast Histology
 
Lotame Animated Presentation
Lotame Animated PresentationLotame Animated Presentation
Lotame Animated Presentation
 

Similaire à How to disassemble one monster app into an ecosystem of 30

RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...jpalley
 
Rails vs Web2py
Rails vs Web2pyRails vs Web2py
Rails vs Web2pyjonromero
 
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendallRubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendalltutorialsruby
 
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendallRubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendalltutorialsruby
 
Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014Lou Sacco
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAERon Reiter
 
More to RoC weibo
More to RoC weiboMore to RoC weibo
More to RoC weiboshaokun
 
Java Technology
Java TechnologyJava Technology
Java Technologyifnu bima
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Angular performance slides
Angular performance slidesAngular performance slides
Angular performance slidesDavid Barreto
 
What's new in Rails 4
What's new in Rails 4What's new in Rails 4
What's new in Rails 4Fabio Akita
 
Java Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App EngineJava Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App EngineIMC Institute
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 3camp
 
Ruby on Rails : RESTful 和 Ajax
Ruby on Rails : RESTful 和 AjaxRuby on Rails : RESTful 和 Ajax
Ruby on Rails : RESTful 和 AjaxWen-Tien Chang
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
ADF Gold Nuggets (Oracle Open World 2011)
ADF Gold Nuggets (Oracle Open World 2011)ADF Gold Nuggets (Oracle Open World 2011)
ADF Gold Nuggets (Oracle Open World 2011)Lucas Jellema
 

Similaire à How to disassemble one monster app into an ecosystem of 30 (20)

RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
Rails vs Web2py
Rails vs Web2pyRails vs Web2py
Rails vs Web2py
 
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendallRubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendall
 
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendallRubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendall
 
Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
 
More to RoC weibo
More to RoC weiboMore to RoC weibo
More to RoC weibo
 
Java Technology
Java TechnologyJava Technology
Java Technology
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Google app engine by example
Google app engine by exampleGoogle app engine by example
Google app engine by example
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Angular performance slides
Angular performance slidesAngular performance slides
Angular performance slides
 
What's new in Rails 4
What's new in Rails 4What's new in Rails 4
What's new in Rails 4
 
Java Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App EngineJava Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App Engine
 
Google App Engine
Google App EngineGoogle App Engine
Google App Engine
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2
 
Ruby on Rails : RESTful 和 Ajax
Ruby on Rails : RESTful 和 AjaxRuby on Rails : RESTful 和 Ajax
Ruby on Rails : RESTful 和 Ajax
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
ADF Gold Nuggets (Oracle Open World 2011)
ADF Gold Nuggets (Oracle Open World 2011)ADF Gold Nuggets (Oracle Open World 2011)
ADF Gold Nuggets (Oracle Open World 2011)
 

Dernier

The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
WomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyoneWomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyoneUiPathCommunity
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Nikki Chapple
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
QMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdfQMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdfROWELL MARQUINA
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentMahmoud Rabie
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 

Dernier (20)

The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
WomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyoneWomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyone
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
QMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdfQMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdf
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career Development
 
How Tech Giants Cut Corners to Harvest Data for A.I.
How Tech Giants Cut Corners to Harvest Data for A.I.How Tech Giants Cut Corners to Harvest Data for A.I.
How Tech Giants Cut Corners to Harvest Data for A.I.
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 

How to disassemble one monster app into an ecosystem of 30

  • 1. From 1 To 30 How To Disassemble One Monster App Into An Ecosystem Of 30 Beta 技术沙龙 http://club.blogbeta.com 官方twitter : @betasalon Groups : http:// groups.google.com/group/betasalon Jonathan Palley, CTO/COO Guo Lei, Chief Architect © 2010 Idapted, Ltd.
  • 3. A Tale of Two Buildings
  • 4. 2009 Shanghai Lotus Riverside Community 1909 Beijing Forbidden City
  • 7. The entire web application/system/platform runs as one single rails application (We are talking about really large systems. Multiple different types of clients/functions)
  • 8. Problems Confused new staff Hard to test/extend/scale
  • 10. A ecosystem of applications
  • 13. Basic features of each app • Separate database • Runs independently (complete story) • Lightweight (single developer) • Tight internal cohesion and loose external coupling Advantages • Independent Development Cycle • Developer autonomy • Technology (im)maturity safety APPEAL TO DEVELOPER LAZINESS
  • 14. What’s the mystery of the forbidden city?
  • 15. Consistent UI • Shared CSS/JS/Styleguide • Common Helpers in Shared Gem • Safely try new things
  • 16. interface All applications use the same base CSS/JS Keep all the application the same style <%= idp_include_js_css %> # => <script src ="/assets/javascripts/frame.js" type="text/javascript"></script> <link href="/assets/stylesheets/frame.css" media="screen" rel="stylesheet" type="text/css" />
  • 17. interface CSS Framework
  • 18. interface Abstract Common Helpers to Gem Search function for models
  • 19. interface Common Helpers: Combo search (cont) View: <%= search_form_for(HistoryRecord, :interaction_id, :released,[:rating, {:collection=>assess_ratings}],[:mark_spot_num,{:range=>true}], [:created_at, {:ampm=>true}]) %> Controller: @history_records = HistoryRecord.combo_search(params)
  • 20. interface Common Helpers: List table well formatted sortable with pagination customizable
  • 21. interface Common Helpers: List table (cont) <%= idp_table_for(@history_records,:sortable=>true,:customize => "history_records") do |item, col| col.add :id, link_to(item.id, admin_history_record_path(item)),:order=>:id col.build :duration, :waiting_time, :review_time col.add :scenario, item.scenario_title, :order => :scenario_title col.add :mark_spot_num end %>
  • 22. interface Development Lifecycle 1. Implement new View code/plugin in a second application 2. Abstract into plugin using existing “idp” helpers 3. Put it into main view gem
  • 23. interface data
  • 24. data How do applications share data? (remember: each app has its own data) -“Read Only” Database Connections - Services - AJAX Loaded View Segments
  • 25. data Business example user purchase course learning process
  • 26. data Purchase App Requirement: List course packages for user to select to purchase but The course package data is stored in the “course” application
  • 27. data Solution readonly db connection course
  • 28. data Code Model: class CoursePackage < ActiveRecord::Base acts_as_readonly :course end View: <ul> <% CoursePackage.all.each do |package| %> <li><%= package.title %> <%= package.price %></li> <% end %> </ul>
  • 29. data Why doesn’t this break the rule of loose coupling? Model: class CoursePackage < ActiveRecord::Base acts_as_readonly :course end View: <ul> <% CoursePackage.all.each do |package| %> <li><%= package.title %> <%= package.price %></li> <% end %> </ul>
  • 30. data acts_as_readonly in Depth def acts_as_readonly(name, options = {}) config = CoreService.app(name).database establish_connection config[Rails.env] set_table_name(self.connection.current_database + (options[:table_name]||table_name).to_s) end
  • 31. data acts_as_readonly in Depth def acts_as_readonly(name, options = {}) config = CoreService.app(name).database establish_connection config[Rails.env] set_table_name(self.connection.current_database + (options[:table_name]||table_name).to_s) end
  • 32. data Core service class CoreService < ActiveResource::Base self.site = :user def self.app(app_name) CoreService.find(app_name) end end
  • 33. data Centralized configuration How does Core know all the configurations?
  • 34. data Each app posts its configuration to core when it is started
  • 35. data config/site_config.yml app: course api: course_list: package/courses config/initializers/idp_initializer.rb CoreService.reset_config
  • 36. data core_service.rb in idp_lib APP_CONFIG = YAML.load(Rails.root.join(“config/site_config.yml”)) def reset_config self.post(:reset_config, :app => { :name => APP_CONFIG["app"], :settings => APP_CONFIG, :database => YAML.load_file( Rails.root.join("config/database.yml"))}) end
  • 37. data Model in Purchase: class CoursePackage < ActiveRecord::Base acts_as_readonly :course end
  • 38. data Again, implemented in gem config/environment.rb config.gem ‘idp_helpers’ config.gem ‘idp_lib’
  • 39. data gems
  • 40. data • Web services for “write” interactions class CoursePackageService < ActiveSupport::Base self.site = :course end
  • 41. data example Roadmap needs to be generated after learner pays.
  • 42. data codes Course: app/controllers/roadmap_services_controller.rb def create Roadmap.generate(params[:user_id], params[:course_id]) end Purchase: app/models/roadmap_service.rb class RoadmapService < ActiveSupport::Base self.site = :course end Purchase: app/models/order.rb def activate_roadmap RoadmapService.create(self.user_id, self.course_id) end
  • 43. data AJAX Loaded Composite View <div> <%= ajax_load(url_of(:course, :course_list)) %> </div> Ecosystem url_for Fetched from different applications
  • 44. data Open Source http://github.com/idapted/eco_apps
  • 45. interface data user
  • 46. user Features of User Service • Registration/login • Profile management • Role Based Access Control
  • 47. user Access Control Each Controller is one Node * Posted to user service when app starts
  • 48. user Access Control before_filter :check_access_right def check_access_right unless xml_request? or inner_request? access_denied unless has_page_right?(params[:controller]) end end * Design your apps so access control can be by controller!
  • 49. user How to share?
  • 50. user Step 1: User Auth SSO Shared Session Same Session Store
  • 51. user Step 1: User Auth config/initializers/idp_initializer.rb ActionController::Base.session_store = :active_record_store ActiveRecord::SessionStore::Session.acts_as_remote :user, :readonly => false
  • 52. user Step 2: Access Control Tell core its controllers structure CoreService. reset_rights def self.reset_rights data = load_controller_structure self.post(:reset_rights, :data => data) end
  • 53. user Step 2: Access Control before_filter :check_access_right def check_access_right unless xml_request? or inner_request? access_denied unless has_page_right?(params[:controller]) end end
  • 54. user Step 2: Access Control has_page_right? Readonly db conn again
  • 55. user Step 2: Access Control class IdpRoleRight < ActiveRecord::Base acts_as_readonly :user, :table_name => "role_rights" end def has_page_right?(page) roles = current_user.roles roles_of_page = IdpRoleRight.all(:conditions => ["path = ?", page]).map(&:role_id) (roles - (roles - roles_of_page)).size > 0 end
  • 56. user Again, gems! config/environment.rb config.gem ‘idp_helpers’ config.gem ‘idp_lib’ config.gem ‘idp_core’
  • 57. interface data user service
  • 58. service Support applications • File • Mail • Comet service
  • 59. File Specify Class that class Article < ActiveRecord::Base Has Files has_files end Upload File in Background to Idp_file_form FileService Store with app_name, model_name, model_id Use readonly magic to easily @article.files.first.url display
  • 60. service Comet class ChatRoom < ActiveRecord::Base acts_as_realtime end <%= realtime_for(@chat_room, current_user.login) %> <%= realtime_data(dom_id, :add, :top) %> @chat_room.realtime_channel.broadcast (“hi world", current_user.login)
  • 61. service mail Mail services MailService.send(“test@idapted.com”, :welcome, :user => “test”)
  • 62. Host all in one domain Load each rails app into a subdir, we use Unicorn unicorn_rails --path /user unicorn_rails --path /studycenter unicorn_rails --path /scenario
  • 63. Host all in one domain use Nginx as a reverse proxy location /user { proxy_pass http://rails_app_user; } location /studycenter { proxy_pass http://rails_app_studycenter; }
  • 64. Host all in one domain All you see is a uniform URL www.eqenglish.com/user www.eqenglish.com/studycenter www.eqenglish.com/scenario
  • 65.
  • 67. How to split one into many?
  • 68. By Story Each App is one group of similar features. By Data Each App writes to the same data
  • 69. Example • User Management • Course package • Purchase • Learning process • …
  • 71. Be adventurous at the beginning. Split one into as many as you think is sensitive
  • 72. Then you may find • Some applications interact with each other frequently. • Lots of messy and low efficiency code to deal with interacting.
  • 74. Measurement • Critical and core task of single app should not call services of others. • One doesn’t need to know much about others’ business to do one task (or develop). • Independent Stories
  • 75. Pitfalls • Applications need to be on the same intranet. • No “right place” for certain cases.
  • 76. Results: Higher Productivity -Faster build to deploy -More developer autonomy -Safer - Scalable -Easier to “jump in” - Greater Happiness
  • 77. Support Tech • FreeSWITCH • VoIP • http://www.freeswitch.org.cn • Flex • Erlang • concurrent tasks • Titanium • mobile
  • 78. Full Stack of Us CTO Rails/Flex VoIP UI UE System
  • 79. Full Stack of Us Develop environment: • 4 mbp + 4 black apples + 1 linux • textmate & netbeans Servers: • test: 2 physical pc with Xen serving 10 virtual servers • production: 2 (China) + 5(US)
  • 80. Full Stack of Us Web Server: • nginx + unicorn Rails: • Rails version 2.3.4 • Ruby version: 1.8.7
  • 81. Full Stack of Us Plugins: • exception_notification • will_paginate • in_place_editor_plus • acts_as_list • open_flash_chart • Spawn + workling
  • 82. Full Stack of Us Gems: • rspec • factory_girl • thinking-sphinx DB: • mysql Cache: • memcache
  • 83. Full Stack of Us Test: • rspec + factory_girl • Autospec Deploy: • webistrano
  • 84. Full Stack of Us Team Build: • board • code review • tea break • retreat
  • 85. Join Us If you are: • smart • creative • willing to do great things with great people • happen to know JS/Flex/Rails Send whatever can prove your ability to: tech-team-jobs@idapted.com
  • 86. Thank you! Q&A http://developer.idapted.com jpalley@idapted.com (@jpalley) guolei@idapted.com (@fiyuer) © 2010 Idapted, Ltd.