SlideShare une entreprise Scribd logo
1  sur  26
Télécharger pour lire hors ligne
Riding the Rails
@
DigitalOcean
• Shared business logic as an engine
• Form objects
• MySQL table as KV store
• Abusing ASN for cleanliness
gem 'core',
git: 'https://githubenterprise/digitalocean/core',
ref: '623ac1e785e092f7369d5cfa7e56ea2e98fb2e20'
“Core”
Our Rails Engine in Reverse
“Core”
Our Rails Engine in Reverse
gem 'core',
git: 'https://githubenterprise/digitalocean/core',
ref: '623ac1e785e092f7369d5cfa7e56ea2e98fb2e20'
# lib/blorgh/engine.rb
module Blorgh
class Engine < ::Rails::Engine
isolate_namespace Blorgh
config.to_prepare do
Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
require_dependency(c)
end
end
end
end
# MyApp/app/decorators/models/blorgh/post_decorator.rb
Blorgh::Post.class_eval do
def time_since_created
Time.current - created_at
end
end
:thumbsdown:
# MyApp/app/models/blorgh/post.rb
class Blorgh::Post < ActiveRecord::Base
include Blorgh::Concerns::Models::Post
def time_since_created
Time.current - created_at
end
def summary
"#{title} - #{truncate(text)}"
end
end
:thumbsdown:
# Blorgh/lib/concerns/models/post
module Blorgh::Concerns::Models::Post
extend ActiveSupport::Concern
# 'included do' causes the included code to be evaluated in the
# context where it is included (post.rb), rather than being
# executed in the module's context (blorgh/concerns/models/post).
included do
attr_accessor :author_name
belongs_to :author, class_name: "User"
before_save :set_author
private
def set_author
self.author = User.find_or_create_by(name: author_name)
end
end
end
require_dependency Core::Engine.root.join('app', 'models', 'droplet').to_s
class Droplet
BACKUP_CHARGE_PERCENTAGE = 0.20
def monthly_backup_price
self.size.monthly_price * BACKUP_CHARGE_PERCENTAGE
end
end
:thumbsup:
Previously...
# app/controllers/events_controller.rb
event = Event.new(
:event_scope => 'droplet',
:event_type => params[:event_type], # from the route
:droplet_id => params[:droplet_id],
:image_id => params[:image_id],
:size_id => params[:size_id],
:user_id => current_user.id,
:name => name
)
# app/models/event.rb
# Validations Based on Event Type
case self.event_type
when 'resize'
errors.add(:size_id, "...") if size_id == droplet.size_id
errors.add(:size_id, "...") unless Size.active.include? size_id
end
class Resize
extend ActiveModel::Naming
include ActiveModel::Conversion
include ActiveModel::Validations
include Virtus
attribute :size, Size
attribute :user, User
attribute :droplet, Droplet
validates :size,
allowed_size: true,
presence: true
def save
if valid?
event.save!
else
false
end
end
def persisted?
false
end
def event
@_event ||= EventFactory.build(:resize, event_params)
end
end
# app/views/resizes/_form.erb
= form_for [@droplet, Resize.new] do |f|
= render 'sizes', sizes: @sizes_available_for_resize, form: f
= f.submit 'Resize'
class ResizesController < ApplicationController
def create
droplet = current_user.droplets.find(params[:droplet_id])
size = Size.active.where(id: params[:size_id]).first
resize = Resize.new(droplet: droplet, size: size)
if resize.save
redirect_to resize.droplet, notice: 'Your resize is processing'
else
redirect_to resize.droplet, alert: resize.errors.first
end
end
end
<3Virtus
• Validations are contextual
• Slims down god objects
• Can be tested without ActiveRecord
• Makes testing ActiveRecord classes easier
WARNING:
YOU
PROBABLY
SHOULD
NOT
DO
THIS
CREATE TABLE `user_properties` (
`user_id` int(11) NOT NULL,
`name` varchar(32) NOT NULL DEFAULT '',
`value` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`user_id`,`name`),
KEY `name` (`name`,`value`),
KEY `user_id` (`user_id`,`name`,`value`)
)
class User
include Propertable
property :marked_as_sketchy_at, nil, :date_time
property :marked_as_verified_at, nil, :date_time
property :marked_as_abuse_at, nil, :date_time
property :marked_as_hold_at, nil, :date_time
property :marked_as_suspended_at, nil, :date_time
property :marked_as_review_at, nil, :date_time
end
module Propertable
def property(name, default, type = :string)
key = name.to_s
props = class_variable_get(:@@properties)
props[key] = default
define_method(key) do
property = __read_property__(key)
if property.nil? || property == default
default
else
Propertable::Coercer.call(property.value, property.value.class, type)
end
end
define_method("#{key}?") do
!!public_send(key)
end
define_method("#{key}=") do |value|
begin
coerced_value = Propertable::Coercer.call(value, value.class, type)
rescue
coerced_value = default
end
coerced_value = Propertable::Coercer.call(coerced_value, type.class, :string)
property = __write_property__(key, coerced_value)
end
end
end
ASN = ActiveSupport::Notifications
INSTRUMENT
EVERYTHING!
$statsd = Statsd.new(statsd_ip).tap { |s| s.namespace = Rails.env }
# Request Times
ActiveSupport::Notifications.subscribe /process_action.action_controller/ do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
status = event.payload[:status]
key = "requests.cloud"
$statsd.timing "#{key}.time.total", event.duration
$statsd.timing "#{key}.time.db", event.payload[:db_runtime]
$statsd.timing "#{key}.time.view", event.payload[:view_runtime]
$statsd.increment "#{key}.status.#{status}"
end
# SQL Queries
ActiveSupport::Notifications.subscribe 'sql.active_record' do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
key = 'queries.cloud'
$statsd.increment key
$statsd.timing key, event.duration
end
module Instrumentable
extend ActiveSupport::Concern
included do
build_instrumentation
end
module ClassMethods
def build_instrumentation
key = name.underscore + '.callbacks'
after_commit(on: :create) do |record|
ASN.instrument key, attributes: record.attributes, action: 'create'
end
after_rollback do |record|
ASN.instrument key, attributes: record.attributes, action: 'rollback'
end
end
end
end
ActiveSupport::Notifications.subscribe 'event.callbacks' do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
type_id = event.payload[:attributes]['event_type_id']
action = event.payload[:action]
EventInstrumenter.perform_async(type_id, action)
end
after_commit(on: :update) do |record|
ASN.instrument key,
attributes: record.attributes,
changes: record.previous_changes,
action: 'update'
end
class TicketNotifier < BaseNotifier
setup :ticket
def created(ticket)
notify_about_admin_generated_ticket!(ticket) if ticket.opened_by_admin?
end
def updated(ticket, changes)
if category = modification(changes, 'category')
notify_networking(ticket) if category == 'networking'
notify_about_escalated_ticket(ticket) if category == 'engineering'
end
end
private
# TODO: move to base
def modification(changes, key)
changes.has_key?(key) && changes[key].last
end
end
ESB = ASN = ActiveSupport::Notifications
We’re Hiring!
module Rack
class Audit
def call(env)
audit = Thread.current[:audit] = {}
audit[:request] = Rack::Request.new(env)
@app.call(env)
end
end
end

Contenu connexe

Tendances

iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative versionWO Community
 
Simpler Core Data with RubyMotion
Simpler Core Data with RubyMotionSimpler Core Data with RubyMotion
Simpler Core Data with RubyMotionStefan Haflidason
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignLightbend
 
Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']Jan Helke
 
Effective cassandra development with achilles
Effective cassandra development with achillesEffective cassandra development with achilles
Effective cassandra development with achillesDuyhai Doan
 
Introduction to AJAX In WordPress
Introduction to AJAX In WordPressIntroduction to AJAX In WordPress
Introduction to AJAX In WordPressCaldera Labs
 
Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleKaty Slemon
 
Dart and AngularDart
Dart and AngularDartDart and AngularDart
Dart and AngularDartLoc Nguyen
 
Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSVisual Engineering
 
Webapps without the web
Webapps without the webWebapps without the web
Webapps without the webRemy Sharp
 
AngularJS $http Interceptors (Explanation and Examples)
AngularJS $http Interceptors (Explanation and Examples)AngularJS $http Interceptors (Explanation and Examples)
AngularJS $http Interceptors (Explanation and Examples)Brian Swartzfager
 
Requirejs
RequirejsRequirejs
Requirejssioked
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorialClaude Tech
 
AngularJS Tips&Tricks
AngularJS Tips&TricksAngularJS Tips&Tricks
AngularJS Tips&TricksPetr Bela
 
How routing works in angular js
How routing works in angular jsHow routing works in angular js
How routing works in angular jscodeandyou forums
 
Workshop 24: React Native Introduction
Workshop 24: React Native IntroductionWorkshop 24: React Native Introduction
Workshop 24: React Native IntroductionVisual Engineering
 

Tendances (20)

iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative version
 
Simpler Core Data with RubyMotion
Simpler Core Data with RubyMotionSimpler Core Data with RubyMotion
Simpler Core Data with RubyMotion
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
 
Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']
 
Effective cassandra development with achilles
Effective cassandra development with achillesEffective cassandra development with achilles
Effective cassandra development with achilles
 
Introduction to AJAX In WordPress
Introduction to AJAX In WordPressIntroduction to AJAX In WordPress
Introduction to AJAX In WordPress
 
Oak Lucene Indexes
Oak Lucene IndexesOak Lucene Indexes
Oak Lucene Indexes
 
Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with example
 
Dart and AngularDart
Dart and AngularDartDart and AngularDart
Dart and AngularDart
 
Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJS
 
Ansible modules 101
Ansible modules 101Ansible modules 101
Ansible modules 101
 
Webapps without the web
Webapps without the webWebapps without the web
Webapps without the web
 
AngularJS $http Interceptors (Explanation and Examples)
AngularJS $http Interceptors (Explanation and Examples)AngularJS $http Interceptors (Explanation and Examples)
AngularJS $http Interceptors (Explanation and Examples)
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Requirejs
RequirejsRequirejs
Requirejs
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorial
 
AngularJS Tips&Tricks
AngularJS Tips&TricksAngularJS Tips&Tricks
AngularJS Tips&Tricks
 
How routing works in angular js
How routing works in angular jsHow routing works in angular js
How routing works in angular js
 
Workshop 24: React Native Introduction
Workshop 24: React Native IntroductionWorkshop 24: React Native Introduction
Workshop 24: React Native Introduction
 
Geotalk presentation
Geotalk presentationGeotalk presentation
Geotalk presentation
 

En vedette

Environment AND technology
Environment AND technologyEnvironment AND technology
Environment AND technologyaditya_12
 
Technology environment in_india_and_the_world[1]
Technology environment in_india_and_the_world[1]Technology environment in_india_and_the_world[1]
Technology environment in_india_and_the_world[1]Zoeb Matin
 
Using Technology to Monitor Marine Environments
Using Technology to Monitor Marine EnvironmentsUsing Technology to Monitor Marine Environments
Using Technology to Monitor Marine Environmentstcooper66
 
technology and environment
technology and environmenttechnology and environment
technology and environmentRamya SK
 
Role of information technology in environment
Role of information technology in environmentRole of information technology in environment
Role of information technology in environmentRohit Sunkari
 
Techonological environment
Techonological environmentTechonological environment
Techonological environmentMadhu Sudhan
 
Technological environment
Technological environmentTechnological environment
Technological environmentNikita
 
Effect of technology on environment
Effect of technology on environmentEffect of technology on environment
Effect of technology on environmentPadma Lalitha
 
Business and the Technological Environment
Business and the Technological EnvironmentBusiness and the Technological Environment
Business and the Technological Environmenttutor2u
 
Technological environment
Technological environmentTechnological environment
Technological environmentanmolverma24
 
Business Environment
Business EnvironmentBusiness Environment
Business EnvironmentAj Khandelwal
 
Business Environments
Business EnvironmentsBusiness Environments
Business EnvironmentsSaugata Palit
 
Business environment
Business environmentBusiness environment
Business environmentManthan Shah
 
Business environment
Business environmentBusiness environment
Business environmentAnkit Agarwal
 
Business Environment- Features,Meaning,Importance,Objectives & Porter's Model
Business Environment- Features,Meaning,Importance,Objectives & Porter's Model Business Environment- Features,Meaning,Importance,Objectives & Porter's Model
Business Environment- Features,Meaning,Importance,Objectives & Porter's Model Nikhil Soares
 

En vedette (20)

Environment AND technology
Environment AND technologyEnvironment AND technology
Environment AND technology
 
Technology environment in_india_and_the_world[1]
Technology environment in_india_and_the_world[1]Technology environment in_india_and_the_world[1]
Technology environment in_india_and_the_world[1]
 
Using Technology to Monitor Marine Environments
Using Technology to Monitor Marine EnvironmentsUsing Technology to Monitor Marine Environments
Using Technology to Monitor Marine Environments
 
Effects of technology to environment
Effects of technology to environmentEffects of technology to environment
Effects of technology to environment
 
technology and environment
technology and environmenttechnology and environment
technology and environment
 
Technological envt
Technological envtTechnological envt
Technological envt
 
Role of information technology in environment
Role of information technology in environmentRole of information technology in environment
Role of information technology in environment
 
Techonological environment
Techonological environmentTechonological environment
Techonological environment
 
Technological environment
Technological environmentTechnological environment
Technological environment
 
Effect of technology on environment
Effect of technology on environmentEffect of technology on environment
Effect of technology on environment
 
Business and the Technological Environment
Business and the Technological EnvironmentBusiness and the Technological Environment
Business and the Technological Environment
 
Technological Environment
Technological EnvironmentTechnological Environment
Technological Environment
 
Technological Environment
Technological EnvironmentTechnological Environment
Technological Environment
 
Environment vs Technology
Environment  vs TechnologyEnvironment  vs Technology
Environment vs Technology
 
Technological environment
Technological environmentTechnological environment
Technological environment
 
Business Environment
Business EnvironmentBusiness Environment
Business Environment
 
Business Environments
Business EnvironmentsBusiness Environments
Business Environments
 
Business environment
Business environmentBusiness environment
Business environment
 
Business environment
Business environmentBusiness environment
Business environment
 
Business Environment- Features,Meaning,Importance,Objectives & Porter's Model
Business Environment- Features,Meaning,Importance,Objectives & Porter's Model Business Environment- Features,Meaning,Importance,Objectives & Porter's Model
Business Environment- Features,Meaning,Importance,Objectives & Porter's Model
 

Similaire à Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School

Connect.Tech- Swift Memory Management
Connect.Tech- Swift Memory ManagementConnect.Tech- Swift Memory Management
Connect.Tech- Swift Memory Managementstable|kernel
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails TutorialWen-Tien Chang
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 
Ruby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter BootstrapRuby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter BootstrapMarcio Marinho
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Rabble .
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaKazuhiro Sera
 
Drupal Development
Drupal DevelopmentDrupal Development
Drupal DevelopmentJeff Eaton
 
Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) RoundupWayne Carter
 
Spark Sql for Training
Spark Sql for TrainingSpark Sql for Training
Spark Sql for TrainingBryan Yang
 
Can puppet help you run docker on a T2.Micro?
Can puppet help you run docker on a T2.Micro?Can puppet help you run docker on a T2.Micro?
Can puppet help you run docker on a T2.Micro?Neil Millard
 
Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scalascalaconfjp
 
High Performance Django 1
High Performance Django 1High Performance Django 1
High Performance Django 1DjangoCon2008
 
High Performance Django
High Performance DjangoHigh Performance Django
High Performance DjangoDjangoCon2008
 
Module, AMD, RequireJS
Module, AMD, RequireJSModule, AMD, RequireJS
Module, AMD, RequireJS偉格 高
 
Django Multi-DB in Anger
Django Multi-DB in AngerDjango Multi-DB in Anger
Django Multi-DB in AngerLoren Davie
 

Similaire à Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School (20)

Connect.Tech- Swift Memory Management
Connect.Tech- Swift Memory ManagementConnect.Tech- Swift Memory Management
Connect.Tech- Swift Memory Management
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails Tutorial
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
Ruby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter BootstrapRuby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter Bootstrap
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in Scala
 
Drupal Development
Drupal DevelopmentDrupal Development
Drupal Development
 
Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) Roundup
 
Spark Sql for Training
Spark Sql for TrainingSpark Sql for Training
Spark Sql for Training
 
Django Pro ORM
Django Pro ORMDjango Pro ORM
Django Pro ORM
 
Can puppet help you run docker on a T2.Micro?
Can puppet help you run docker on a T2.Micro?Can puppet help you run docker on a T2.Micro?
Can puppet help you run docker on a T2.Micro?
 
Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scala
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
 
High Performance Django 1
High Performance Django 1High Performance Django 1
High Performance Django 1
 
High Performance Django
High Performance DjangoHigh Performance Django
High Performance Django
 
Module, AMD, RequireJS
Module, AMD, RequireJSModule, AMD, RequireJS
Module, AMD, RequireJS
 
Django Multi-DB in Anger
Django Multi-DB in AngerDjango Multi-DB in Anger
Django Multi-DB in Anger
 
Scala active record
Scala active recordScala active record
Scala active record
 
Rails Performance
Rails PerformanceRails Performance
Rails Performance
 

Dernier

Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 

Dernier (20)

Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 

Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School

  • 2. • Shared business logic as an engine • Form objects • MySQL table as KV store • Abusing ASN for cleanliness
  • 3. gem 'core', git: 'https://githubenterprise/digitalocean/core', ref: '623ac1e785e092f7369d5cfa7e56ea2e98fb2e20' “Core” Our Rails Engine in Reverse
  • 4. “Core” Our Rails Engine in Reverse gem 'core', git: 'https://githubenterprise/digitalocean/core', ref: '623ac1e785e092f7369d5cfa7e56ea2e98fb2e20'
  • 5. # lib/blorgh/engine.rb module Blorgh class Engine < ::Rails::Engine isolate_namespace Blorgh config.to_prepare do Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c| require_dependency(c) end end end end # MyApp/app/decorators/models/blorgh/post_decorator.rb Blorgh::Post.class_eval do def time_since_created Time.current - created_at end end :thumbsdown:
  • 6. # MyApp/app/models/blorgh/post.rb class Blorgh::Post < ActiveRecord::Base include Blorgh::Concerns::Models::Post def time_since_created Time.current - created_at end def summary "#{title} - #{truncate(text)}" end end :thumbsdown:
  • 7. # Blorgh/lib/concerns/models/post module Blorgh::Concerns::Models::Post extend ActiveSupport::Concern # 'included do' causes the included code to be evaluated in the # context where it is included (post.rb), rather than being # executed in the module's context (blorgh/concerns/models/post). included do attr_accessor :author_name belongs_to :author, class_name: "User" before_save :set_author private def set_author self.author = User.find_or_create_by(name: author_name) end end end
  • 8. require_dependency Core::Engine.root.join('app', 'models', 'droplet').to_s class Droplet BACKUP_CHARGE_PERCENTAGE = 0.20 def monthly_backup_price self.size.monthly_price * BACKUP_CHARGE_PERCENTAGE end end :thumbsup:
  • 9. Previously... # app/controllers/events_controller.rb event = Event.new( :event_scope => 'droplet', :event_type => params[:event_type], # from the route :droplet_id => params[:droplet_id], :image_id => params[:image_id], :size_id => params[:size_id], :user_id => current_user.id, :name => name ) # app/models/event.rb # Validations Based on Event Type case self.event_type when 'resize' errors.add(:size_id, "...") if size_id == droplet.size_id errors.add(:size_id, "...") unless Size.active.include? size_id end
  • 10. class Resize extend ActiveModel::Naming include ActiveModel::Conversion include ActiveModel::Validations include Virtus attribute :size, Size attribute :user, User attribute :droplet, Droplet validates :size, allowed_size: true, presence: true def save if valid? event.save! else false end end def persisted? false end def event @_event ||= EventFactory.build(:resize, event_params) end end
  • 11. # app/views/resizes/_form.erb = form_for [@droplet, Resize.new] do |f| = render 'sizes', sizes: @sizes_available_for_resize, form: f = f.submit 'Resize' class ResizesController < ApplicationController def create droplet = current_user.droplets.find(params[:droplet_id]) size = Size.active.where(id: params[:size_id]).first resize = Resize.new(droplet: droplet, size: size) if resize.save redirect_to resize.droplet, notice: 'Your resize is processing' else redirect_to resize.droplet, alert: resize.errors.first end end end
  • 12. <3Virtus • Validations are contextual • Slims down god objects • Can be tested without ActiveRecord • Makes testing ActiveRecord classes easier
  • 14. CREATE TABLE `user_properties` ( `user_id` int(11) NOT NULL, `name` varchar(32) NOT NULL DEFAULT '', `value` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`user_id`,`name`), KEY `name` (`name`,`value`), KEY `user_id` (`user_id`,`name`,`value`) ) class User include Propertable property :marked_as_sketchy_at, nil, :date_time property :marked_as_verified_at, nil, :date_time property :marked_as_abuse_at, nil, :date_time property :marked_as_hold_at, nil, :date_time property :marked_as_suspended_at, nil, :date_time property :marked_as_review_at, nil, :date_time end
  • 15. module Propertable def property(name, default, type = :string) key = name.to_s props = class_variable_get(:@@properties) props[key] = default define_method(key) do property = __read_property__(key) if property.nil? || property == default default else Propertable::Coercer.call(property.value, property.value.class, type) end end define_method("#{key}?") do !!public_send(key) end define_method("#{key}=") do |value| begin coerced_value = Propertable::Coercer.call(value, value.class, type) rescue coerced_value = default end coerced_value = Propertable::Coercer.call(coerced_value, type.class, :string) property = __write_property__(key, coerced_value) end end end
  • 18. $statsd = Statsd.new(statsd_ip).tap { |s| s.namespace = Rails.env } # Request Times ActiveSupport::Notifications.subscribe /process_action.action_controller/ do |*args| event = ActiveSupport::Notifications::Event.new(*args) status = event.payload[:status] key = "requests.cloud" $statsd.timing "#{key}.time.total", event.duration $statsd.timing "#{key}.time.db", event.payload[:db_runtime] $statsd.timing "#{key}.time.view", event.payload[:view_runtime] $statsd.increment "#{key}.status.#{status}" end # SQL Queries ActiveSupport::Notifications.subscribe 'sql.active_record' do |*args| event = ActiveSupport::Notifications::Event.new(*args) key = 'queries.cloud' $statsd.increment key $statsd.timing key, event.duration end
  • 19.
  • 20. module Instrumentable extend ActiveSupport::Concern included do build_instrumentation end module ClassMethods def build_instrumentation key = name.underscore + '.callbacks' after_commit(on: :create) do |record| ASN.instrument key, attributes: record.attributes, action: 'create' end after_rollback do |record| ASN.instrument key, attributes: record.attributes, action: 'rollback' end end end end
  • 21. ActiveSupport::Notifications.subscribe 'event.callbacks' do |*args| event = ActiveSupport::Notifications::Event.new(*args) type_id = event.payload[:attributes]['event_type_id'] action = event.payload[:action] EventInstrumenter.perform_async(type_id, action) end
  • 22. after_commit(on: :update) do |record| ASN.instrument key, attributes: record.attributes, changes: record.previous_changes, action: 'update' end
  • 23. class TicketNotifier < BaseNotifier setup :ticket def created(ticket) notify_about_admin_generated_ticket!(ticket) if ticket.opened_by_admin? end def updated(ticket, changes) if category = modification(changes, 'category') notify_networking(ticket) if category == 'networking' notify_about_escalated_ticket(ticket) if category == 'engineering' end end private # TODO: move to base def modification(changes, key) changes.has_key?(key) && changes[key].last end end
  • 24. ESB = ASN = ActiveSupport::Notifications
  • 26. module Rack class Audit def call(env) audit = Thread.current[:audit] = {} audit[:request] = Rack::Request.new(env) @app.call(env) end end end