Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Ruby For Startups
1. Startup Ruby
Separate things that change from things
that stay the same
Program to an interface, not an
implementation
Prefer composition over inheritance
Delegate, delegate, delegate
You Ain't Gonna Need It (YAGNI)
8. Separate things that change from things
that stay the same
Program to interfaces, not implementations
Prefer composition over inheritance
Delegate, delegate, delegate
You Ain't Gonna Need It (YAGNI)
9. Design for Change
"Separate code for general functionality from
code for specialized functionality"
Isolate design decisions in their own modules
10. First Use of SQS
SQS =
RightAws::SqsGen2.new(access_key_i
d, secret_access_key], { :multi_thread
=> true })
queue =
SQS.queue("#{RAILS_ENV}_#{queue_name
}")
11. First Use of SQS
SQS =
RightAws::SqsGen2.new(access_key_i
d, secret_access_key], { :multi_thread
=> true })
queue =
SQS.queue("#{RAILS_ENV}_#{queue_name
}")
Then both of these changed
12. Designed for Change
queue =
QueueFetcher.fetch(queue_name)
queue.send_message({ :user_id =>
user_id }.to_yaml
Isolates how we connect to the messaging system
Isolates naming convention for the messaging system
13. class QueueFetcher
def self.fetch(queue_name)
SQS2.queue("#{queue_env}_#{queue_name}")
end
private
def self.queue_env
APP_CONFIG['queue_context']
end
end
14. class QueueFetcher
def self.fetch(queue_name)
SQS2.queue("#{queue_env}_#{queue_name}")
end
private
def self.queue_env
APP_CONFIG['queue_context']
end
end
More isolation
15. I don’t like this
class QueueFetcher
def self.fetch(queue_name)
SQS2.queue("#{queue_env}_#{queue_name}")
end
private
def self.queue_env
APP_CONFIG['queue_context']
end
end
More isolation
16. Business Logic
class Envelope
def deliver_first_message
new_mailbox_name = Mailbox.new_mailbox_name(recipient)
mailbox = Mailbox.create!(:user_id => user_id, :name => new_mailbox_name)
prepare_delivery_for_spam
prepare_delivery_for_forwarding(mailbox)
self.first_message = true
return deliver(mailbox)
end
17. Program to
interfaces, not
implementations
Program to general types
"Don’t call it a car if you can get
away with calling it a vehicle"
18. Program to
interfaces, not
implementations
Easy for us to do with duck-typing
19. class Message < ActiveRecord::Base
end
class ArticleMessage < Message
end
class SmtpMessage < Message
end
class SentMessage < Message
end
20. class Message < ActiveRecord::Base
end
?
class ArticleMessage < Message
end
class SmtpMessage < Message
end
class SentMessage < Message
end
21. Prefer composition
over inheritance
Equip objects with references to
other objects which implement
common behavior
23. class Attachment < ActiveRecord::Base
include S3MessageContent
belongs_to :message
before_create :put_attachment_on_s3
before_destroy :remove_from_s3
end
24. Delegate, delegate,
delegate
Objects express certain
outward behavior
but actually delegate responsibility for
that behavior to another object
38. YAGNI
Be a duct tape programmer
“...any kind of coding technique that’s
even slightly complicated is going to
doom your project.”
http://www.joelonsoftware.com/items/
2009/09/23.html
44. Make careful use of
concurrency
Prefer processes communicating
via message bus
(SQS, Starling, delayed_job,
Rabbit MQ, etc.)
45. Make careful use of
concurrency
Check out Unicorn
http://tomayko.com/writings/unicorn-is-unix
46. Make careful use of
concurrency
Threading: EventMachine is your friend
47. Make careful use of
concurrency
Threading: EventMachine is your friend
EMH.safe_defer do
begin
UserMailer.deliver_verification_email(@user, @email)
rescue StandardError
logger.warn("Unable to deliver signup verification
to #{@user.login} due to #{$!.message}")
end
end
49. Consider your RDBMS
relationship
Avoid touching the DB when storing
non-critical data
50. Consider your RDBMS
relationship
Avoid touching the DB when storing
non-critical data
Don’t use an RDBMS for
things it’s not good at
51. Consider your RDBMS
relationship
Avoid touching the DB when storing
non-critical data
Don’t use an RDBMS for
things it’s not good at
We rely heavily on AWS
52. Consider your RDBMS
relationship
Storing large text blobs (S3)
Messaging system (SQS)
Logging events (SimpleDB)
Caching dynamic text (S3)
53. Consider your RDBMS
relationship
We use data_fabric gem to make
master-slave transparent
73. Bundle complex view
logic into Presenters
class RefreshController < ApplicationController
before_filter :signin_required
def index
render :text => JSON.generate(AdvancedRefresher.new(params).to_hash)
end
end