SlideShare ist ein Scribd-Unternehmen logo
1 von 26
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 

Andere mochten auch

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
 

Andere mochten auch (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
 

Ähnlich wie 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
High Performance DjangoHigh Performance Django
High Performance DjangoDjangoCon2008
 
High Performance Django 1
High Performance Django 1High Performance Django 1
High Performance Django 1DjangoCon2008
 
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
 

Ähnlich wie 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
High Performance DjangoHigh Performance Django
High Performance Django
 
High Performance Django 1
High Performance Django 1High Performance Django 1
High Performance Django 1
 
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
 

Kürzlich hochgeladen

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 

Kürzlich hochgeladen (20)

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 

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