Upcoming SlideShare
Loading in...5







Total Views
Views on SlideShare
Embed Views



0 Embeds 0

No embeds



Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment
  • Show a demo of competitious here…

competitious-ruby-si.. competitious-ruby-si.. Presentation Transcript

  • Competitious on Rails Kris Rasmussen, Andrew Holt
  • Competitious on Rails
    • Who we are
    • What is Competitious
    • Why Ruby on Rails?
    • Pros/Cons
    • Competitious code
  • Andrew’s Background
    • B.S. in Computer Science from Stanford
    • Engineer and project manager at Yahoo!
    • Co-founded Revunity
    • Interim creations
    • Co-founded RivalSoft (Competitious)
  • Kris’ Background
    • Web and mobile 3D graphics engines
    • CS and Math from UCLA
    • Internet design and engineering consultant
    • Software Engineer at Microsoft
      • Sharepoint -> worked on blogs, scripting security, wikis, UI, and extensibility of the platform
    • Started, built on top of a scalable, drag and drop AJAX based vertical content management platform
    • Started Competitious
  • Competitious
    • Online service that enables companies to better discover, organize, and analyze data on competition
    • Initial beta release in October, 2006
    • Plan to change the way companies consume and act on competitive information
  • Considering Web Technologies
    • Development speed
    • Libraries + Frameworks
    • Scalability
    • Maintainability
      • MVC
      • Components, Templating
      • Code readability
      • Code size
  • Why we chose Ruby on Rails
    • Less configuration and plumbing code required
    • No template languages
    • Easier to test, and iteratively develop
    • Less emphasis on broad packaged components
    • Elegant and familiar syntax
    • Non-bloated JS libraries and slick AJAX
  • It worked!
    • We built the first version of Competitious in 3 weeks!
    • Partials and Helpers enabled common functionality to be shared much more easily than component based frameworks
    • We have been able to constantly evolve the service and the database and respond quickly to customer feedback
  • But there are problems...
    • Refactoring code is difficult
    • Single threaded/memory heavy processes
    • Needs some work to get “production mode” really ready for production
    • Does not support some complex queries
    • Fetches all the data, all the time
    • Easy to over-query the database
  • Production Checklist
    • Automatic deployment – SVN + Capistrano + Mongrel
    • Filter sensitive data out of logs
      • filter_parameter_logging :password
    • Store sessions in memory or in the database
      • Clear them when they expire
    • Keep database round trips to a minimum, cache when necessary
    • Ensure your Web Server is serving static files!
    • Security reviews: cross site scripting, sql injection, and permissions on objects when referencing by id
      • Don’t rely on with_scope!
  • Glimpse into Competitious
    • Not fully RESTful yet
    • Lots of Many to many relationships, don’t limit yourself unless performance really is an issue
    • Acts as everything
      • Acts_as_noteable
      • Acts_as_loggable (more on this later)
      • Acts_as_securable
      • Acts_as_taggable
      • Acts_as_mediable
    • 19 controllers, 18 models
  • Biggest Performance Issue
    • Waiting on other services…
      • When other services go down or respond slowly your service shouldn’t
    • Why is this a problem
      • You can’t run many rails processes at once (memory)
      • You can’t count on 3 rd parties
  • Step 1 : Caching
    • Reduce number of times you have to wait.
      • Simple time based ObjectCache
        • data = ObjectCache.cache(key,CACHE_TIME) do request_3 rd _party_data(key) end
    • Reduces average wait time but users will still encounter worst wait time… for ever.
    • Not all TOS allow you to cache
  • Step 2 : Timeouts
    • Ensure your rails processes are available!
    • status = Timeout::timeout(3) do Net::HTTP.get(url)
    • end
    • When all else fails fall back on cached data
    • Problem : user still has to wait for longer than they should when other data might be ready
  • Step 3 : Asynchronous Polling
    • Start up new processes/threads to communicate with the third party service at the beginning of the request
      • Use lighter weight processes for this (backgroundDRb)
      • If by the end of the request the data is available, then display it
      • If not then use AJAX to *poll* the server after the page is rendered
  • Making AJAX more responsive
    • Don’t hit the server unless absolutely necessary
      • Common when doing in place editing
    • You don’t have to duplicate view logic in Javascript using ugly inner HTML or the DOM.
  • Javascript Templates
    • Write a simple js template engine
    • Example Template
      • <% define_js_template(&quot;new_feature_tmpl&quot;) do %> <tr id=&quot;new-feature-row- %(id) &quot; class=&quot;new-feature-row&quot;> … <% end %>
      • render_js_template(“new_feature_tmpl&quot;,{'id':id,'type':type,'type_name':type_name});
  • How does it work?
    • Rails Generated html is embedded inside hidden textareas
    • Client Javascript loads template and replaces variables with current parameters
    • Advantages: All view code in one place, less server round trips, don’t need to write much Javascript
    • See our Comparison Matrix for an example
  • Activity Logging
    • Problems associated with activity logging:
      • Records may be created/updated/destroy etc in multiple places
      • Each record has different data that should be displayed in the log
      • After records are updated/deleted log entries and references need to be updated
  • acts_as_loggable !
    • Model:
      • acts_as_loggable :name
    • Controller:
      • Media.with_logging(:user =>@current_user) { …. }
      • Use in an around_filter
    • Views:
      • Create partials for rendering log for each loggable type
  • Models
    • class LogEntry < ActiveRecord::Base
    • belongs_to :log_object
    • belongs_to :user
    • end
    • class LogObject < ActiveRecord::Base
    • belongs_to :loggable, :polymorphic => true
    • has_many :log_entries, :dependent=>:destroy
    • end
  • Advanced Usage
    • acts_as_loggable [ :name , :mediable_type , :mediable_id ,{ :mediable => :name }]
    • Media.with_logging( :action =>'published') do
    • @media .update_attribute('published', true )
    • End
    • Media.with_logging(:data=>extradata) {}
    • Acts_as_loggable {|record,extradata| return hash_of_data}
  • Plugin will be posted on our blog
  • Contact Us
    • Kris
      • [email_address]
    • Andrew
      • [email_address]