the architecture of piccollage server
DESCRIPTION
TRANSCRIPT
![Page 1: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/1.jpg)
The Architecture of PicCollage Server
http://godfat.org/slide/2013-01-08-PicCollage.pdf
![Page 2: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/2.jpg)
•PicCollage, Software and Services
Table of Contents
![Page 3: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/3.jpg)
•PicCollage, Software and Services
•Ruby Codes
Table of Contents
![Page 4: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/4.jpg)
•PicCollage, Software and Services
•Ruby Codes
•Miscellaneous Extras
Table of Contents
![Page 5: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/5.jpg)
PicCollageSoftwareServices&
,
![Page 6: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/6.jpg)
•Gemfile
•Procfile
•Rakefile
•rainbows.rb
•concurrency.rb
•config.ru
Ruby Codes
![Page 7: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/7.jpg)
•server.rb
•error.rb
•eagerload.rb
Ruby Codes(Cont.)
•newrelic.rb
•shell.rb
•waiter.rb
![Page 8: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/8.jpg)
•image_util.rb
•run_later.rb
•/search
•/create_and_share
Ruby Codes(Cont.) (Cont.)
![Page 9: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/9.jpg)
•crazy inspect
•who cares backtrace for 404
•assets pipeline and database connection
•fiber stack overflow
•fiber database connection pool
•thread-safe kaminari patch
Miscellaneous Extras
![Page 10: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/10.jpg)
PicCollageSoftwareServices&
,
![Page 11: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/11.jpg)
PicCollage•Make collages of your photos
•Import photos from places
•Touch gestures to rotate, resize, delete
•Double-tap to edit, clip, etc
•Clip photos by outlining the area
•Lots of backgrounds and stickers
![Page 12: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/12.jpg)
PicCollageSoftwareServices&
,
![Page 13: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/13.jpg)
Software•Ruby 1.8.7 -> 1.9.2 -> 1.9.3
![Page 14: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/14.jpg)
Software•Ruby 1.8.7 -> 1.9.2 -> 1.9.3
•Rails 3.1.0.rc4 -> 3.1.0.rc5 -> 3.1.0 ->3.1.3 -> 3.2.1 -> 3.2.2 -> 3.2.3 -> 3.2.5 -> 3.2.6 -> 3.2.7 -> 3.2.8 -> 3.2.9 -> 3.2.10
![Page 15: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/15.jpg)
Software•Ruby 1.8.7 -> 1.9.2 -> 1.9.3
•Rails 3.1.0.rc4 -> 3.1.0.rc5 -> 3.1.0 ->3.1.3 -> 3.2.1 -> 3.2.2 -> 3.2.3 -> 3.2.5 -> 3.2.6 -> 3.2.7 -> 3.2.8 -> 3.2.9 -> 3.2.10
•Sinatra -> Jellyfish
![Page 16: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/16.jpg)
Software•Ruby 1.8.7 -> 1.9.2 -> 1.9.3
•Rails 3.1.0.rc4 -> 3.1.0.rc5 -> 3.1.0 ->3.1.3 -> 3.2.1 -> 3.2.2 -> 3.2.3 -> 3.2.5 -> 3.2.6 -> 3.2.7 -> 3.2.8 -> 3.2.9 -> 3.2.10
•Sinatra -> Jellyfish
•Thin -> Zbatery
![Page 17: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/17.jpg)
Software•Ruby 1.8.7 -> 1.9.2 -> 1.9.3
•Rails 3.1.0.rc4 -> 3.1.0.rc5 -> 3.1.0 ->3.1.3 -> 3.2.1 -> 3.2.2 -> 3.2.3 -> 3.2.5 -> 3.2.6 -> 3.2.7 -> 3.2.8 -> 3.2.9 -> 3.2.10
•Sinatra -> Jellyfish
•Thin -> Zbatery
•Resque -> EM.next_tick or Thread.new -> Sidekiq (?)
![Page 18: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/18.jpg)
PicCollageSoftwareServices&
,
![Page 19: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/19.jpg)
Services•Github
![Page 20: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/20.jpg)
Services•Github
•Heroku Bamboo -> Cedar
![Page 21: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/21.jpg)
Services•Github
•Heroku Bamboo -> Cedar
•Heroku PostgreSQL 9.0 -> 9.2
![Page 22: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/22.jpg)
Services•Github
•Heroku Bamboo -> Cedar
•Heroku PostgreSQL 9.0 -> 9.2
•MongoHQ -> MongoLab
![Page 23: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/23.jpg)
Services•Github
•Heroku Bamboo -> Cedar
•Heroku PostgreSQL 9.0 -> 9.2
•MongoHQ -> MongoLab
•RedisToGo -> OpenRedis
![Page 24: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/24.jpg)
Services•Github
•Heroku Bamboo -> Cedar
•Heroku PostgreSQL 9.0 -> 9.2
•MongoHQ -> MongoLab
•RedisToGo -> OpenRedis
•Memcache (?) -> Memcachier
![Page 25: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/25.jpg)
Services•Github
•Heroku Bamboo -> Cedar
•Heroku PostgreSQL 9.0 -> 9.2
•MongoHQ -> MongoLab
•RedisToGo -> OpenRedis
•Memcache (?) -> Memcachier
•NewRelic
![Page 26: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/26.jpg)
Services•Github
•Heroku Bamboo -> Cedar
•Heroku PostgreSQL 9.0 -> 9.2
•MongoHQ -> MongoLab
•RedisToGo -> OpenRedis
•Memcache (?) -> Memcachier
•NewRelic
•Exceptional
![Page 27: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/27.jpg)
Services•Github
•Heroku Bamboo -> Cedar
•Heroku PostgreSQL 9.0 -> 9.2
•MongoHQ -> MongoLab
•RedisToGo -> OpenRedis
•Memcache (?) -> Memcachier
•NewRelic
•Exceptional
•SendGrid -> Mailgun
![Page 28: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/28.jpg)
•Gemfile
•Procfile
•Rakefile
Ruby Codes
•rainbows.rb
•concurrency.rb
•config.ru
![Page 29: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/29.jpg)
Gemfileruby '1.9.3'source 'http://rubygems.org'
gem 'rails', '3.2.9'gem 'jellyfish'
gem 'pg', :platform => :rubygem 'redis-objects'gem 'dalli'
![Page 30: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/30.jpg)
# servicegem 'newrelic_rpm', :require => falsegem 'exceptional'gem 'apns', :github => 'jpoz/APNS' # ^^^^ needs feedback patch
# serverplatform :ruby do gem 'zbatery', :require => false gem 'em-http-request' gem 'yajl-ruby'end
Gemfile (Cont.)
![Page 31: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/31.jpg)
# uploadgem 'paperclip' # needs various patchesgem 'aws-sdk'
# plistgem 'nokogiri'
# paginationgem 'kaminari' # needs thread-safe patch
# javascriptgem 'jquery-rails'
Gemfile (Cont.)
![Page 32: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/32.jpg)
# make `rails server` work for zbaterygem 'rack-handlers'
# respect rack loggergem 'rack-rails-logger'
# redirect from www to root domaingem 'rack-rewrite'
# cache for APIgem 'rack-cache'
Gemfile (Cont.)
![Page 33: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/33.jpg)
# api clientgem 'rest-core'gem 'rest-more'
# bluebasegem 'bb_more' , :path => 'bluebase'gem 'bb_locales', :path => 'bluebase'gem 'bb_auth' , :path => 'bluebase'gem 'bb_redis' , :path => 'bluebase'
Gemfile (Cont.)
![Page 34: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/34.jpg)
group :assets do gem 'sass-rails' gem 'coffee-rails' gem 'uglifier'end
group :cedar do gem 'rib' gem 'bond' gem 'readline_buffer', :platform => :rubyend
Gemfile (Cont.)
![Page 35: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/35.jpg)
group :test do gem 'minitest' gem 'rr' gem 'webmock' gem 'kramdown'end
group :test do gem 'capybara' gem 'rspec' gem 'rspec-rails'end
Gemfile (Cont.)
![Page 36: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/36.jpg)
•Gemfile
•Procfile
•Rakefile
Ruby Codes
•rainbows.rb
•concurrency.rb
•config.ru
![Page 37: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/37.jpg)
Procfile
web: ruby -r bundler/setup -S zbatery-c config/rainbows.rb-p $PORT -E $RACK_ENV
![Page 38: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/38.jpg)
•Gemfile
•Procfile
•Rakefile
Ruby Codes
•rainbows.rb
•concurrency.rb
•config.ru
![Page 39: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/39.jpg)
task 'test:all' => ['test', 'test:bluebase']
task 'env:test' do Rails.env = 'test'end
Rakefile
![Page 40: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/40.jpg)
task 'test:bluebase' => ['env:test'] do # remove bundler shit gemfile = ENV.delete('BUNDLE_GEMFILE') sh './bin/bluebase-test' ENV['BUNDLE_GEMFILE'] = gemfileend
Rakefile (Cont.)
![Page 41: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/41.jpg)
task :test => ['test:api']
Rakefile (Cont.)
![Page 42: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/42.jpg)
Rakefiletask 'test:api' => ['env:test', 'environment'] do require './config/environments/test' # force rails loaded, otherwise it's # causing too much loading troubles, # by rails' autoloading mechanism Dir['./test/api/*.rb'].each do |test| require test end # ...end
(Cont.)
![Page 43: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/43.jpg)
# this is only available in 1.9.3+if Test::Unit.const_defined?(:RunCount) Test::Unit::RunCount.run_once{ status = Test::Unit::Runner.new.run exit(status) if status != 0 }end
Rakefile (Cont.)
![Page 44: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/44.jpg)
•Gemfile
•Procfile
•Rakefile
Ruby Codes
•rainbows.rb
•concurrency.rb
•config.ru
![Page 45: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/45.jpg)
worker_processes 2 # assume 2 CPU corespreload_app true
l = ::Logger.new($stderr)l.level = case ENV['RACK_ENV'] when 'production' ::Logger::WARN else ::Logger::DEBUG endlogger l
rainbows.rb
![Page 46: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/46.jpg)
rainbows.rbRainbows! do use :EventMachine, :em_client_class => lambda{ require 'concurrency' client = Concurrency. eventmachine_client l.info("Using #{client}") client } worker_connections 64end
(Cont.)
![Page 47: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/47.jpg)
before_fork do |_, _| # don't hold connections on master unless defined?(Zbatery) l.info("Discon' PSQL and Redis...") AR::Base.connection.disconnect! Redis.current.quit
endend
rainbows.rb (Cont.)
![Page 48: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/48.jpg)
after_fork do |_, _| # hold connections on workers unless defined?(Zbatery) l.info("Conn' PSQL and Redis...") Redis.current.connect AR::Base.connection. establish_connection endend
rainbows.rb (Cont.)
![Page 49: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/49.jpg)
EM.error_handler do |e| puts "Err: #{e.inspect}" \ " #{e.backtrace.inspect}" begin ::Exceptional::Catcher.handle(e) ::NewRelic::Agent.instance. error_collector.notice_error(e) rescue Exception => e puts "Err: Exceptional/NewRelic:" \ " #{e.inspect}" \ " #{e.backtrace.inspect}" endend
rainbows.rb (Cont.)
![Page 50: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/50.jpg)
Rainbows! EventMachine Thread Client
https://gist.github.com/4451322https://github.com/godfat/rainbows/pull/2
rainbows.rb (Cont.)
![Page 51: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/51.jpg)
class ::RainbowsEMThreadPoolClient < Rainbows::EventMachine::Client def app_call input @deferred = true EM.defer do # Call the application here! end endend
rainbows.rb (Cont.)
![Page 52: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/52.jpg)
# Call the application here!begin @env.merge!(RACK_DEFAULTS) status, headers, body = APP.call(@env) @deferred = nil # EM.next_tick? ev_write_response(status, headers, body, @hp.next?)rescue Exception => e EM.instance_variable_get( :@error_handler).call(e) handle_error(e)end
rainbows.rb (Cont.)
![Page 53: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/53.jpg)
•Gemfile
•Procfile
•Rakefile
Ruby Codes
•rainbows.rb
•concurrency.rb
•config.ru
![Page 54: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/54.jpg)
concurrency.rbmodule Concurrency Model = Thread module_function def eventmachine_client if Model == Thread RainbowsEMThreadPoolClient elsif Model == Fiber RainbowsEMFiberSpawnClient else Rainbows::EventMachine::Client end endend
![Page 55: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/55.jpg)
concurrency.rbmodule Concurrency def wrap if Model == Thread EM.defer do # ... end elsif Model == Fiber Fiber.new{ yield }.resume else yield end end
(Cont.)
![Page 56: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/56.jpg)
concurrency.rbdef wrap begin yield rescue Exception => e EM.instance_variable_get( :@error_handler).call(e) ensure AR::Base.clear_active_connections! end
(Cont.)
![Page 57: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/57.jpg)
•Gemfile
•Procfile
•Rakefile
Ruby Codes
•rainbows.rb
•concurrency.rb
•config.ru
![Page 58: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/58.jpg)
config.ruuse Api::HostDispatcher, Api::Server
map '/api' do run Api::Serverend
map '/' do run PicCollage::Applicationend
![Page 59: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/59.jpg)
•server.rb
•error.rb
•eagerload.rb
Ruby Codes(Cont.)
•newrelic.rb
•shell.rb
•waiter.rb
![Page 60: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/60.jpg)
Api::Server = Rack::Builder.new do # Embrace Rack is the Jellyfish wayend
server.rb
![Page 61: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/61.jpg)
use Rack::CommonLogger, debug_loggeruse Rack::Deflateruse Rack::Static, :urls => ['/images'], :root => "#{File.dirname(__FILE__)}/public"
use AR::ConnectionAdapters:: ConnectionManagement
server.rb (Cont.)
![Page 62: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/62.jpg)
use Api::MiddleErroruse Api::MiddleDeviceuse Api::MiddleAuthuse Api::MiddleCacheuse Rack::Cache, {} # [snipped]run Api::ServerCore.new
server.rb (Cont.)
![Page 63: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/63.jpg)
class Api::ServerCore include Jellyfish handle_exceptions false def controller; Controller; end
class Controller < Api::Controller include Api::ServerMethods include Jellyfish::NewRelic endend
server.rb (Cont.)
![Page 64: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/64.jpg)
class Api::ServerCore post '/collages/create_and_share' do render_collage create_collage{ |c| transfer "/collages/#{c.id}/share" } endend
server.rb (Cont.)
![Page 65: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/65.jpg)
•server.rb
•error.rb
•eagerload.rb
Ruby Codes(Cont.)
•newrelic.rb
•shell.rb
•waiter.rb
![Page 66: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/66.jpg)
class Api::MiddleError include Jellyfish handle_exceptions true def controller; Api::Controller; end
handle Api::Error do |error| render(error_custom(error)) endend
error.rb
![Page 67: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/67.jpg)
error.rb (Cont.)class Api::MiddleError handle Jellyfish::NotFound do render(error_custom( Api::NotFound.new( "Path not found."))) end
handle Exception do |error| render(error_500(error)) end
![Page 68: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/68.jpg)
•server.rb
•error.rb
•eagerload.rb
Ruby Codes(Cont.)
•newrelic.rb
•shell.rb
•waiter.rb
![Page 69: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/69.jpg)
module Eagerload module_function def eagerload if ENV['RAILS_GROUPS'] == 'assets' $stderr.puts "Don't eagerload " \ "for assets precompilation." return end # ...
eagerload.rb
![Page 70: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/70.jpg)
def eagerload # ... require 'rest-more' RC.eagerload require 'aws-sdk' RC.eagerload(AWS::Core) RC.eagerload(AWS::S3)
eagerload.rb (Cont.)
![Page 71: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/71.jpg)
def eagerload # ... %w[app/models/**/* app/controllers/**/* app/mailers/**/*]. each{ |pattern| require_all(Dir[pattern], 2) }
eagerload.rb (Cont.)
![Page 72: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/72.jpg)
def eagerload # ... require 'api/requirements' require_all(Dir['lib/**/*'], 1) $stderr.puts "Eagerly loaded." true end
eagerload.rb (Cont.)
![Page 73: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/73.jpg)
•server.rb
•error.rb
•eagerload.rb
Ruby Codes(Cont.)
•newrelic.rb
•shell.rb
•waiter.rb
![Page 74: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/74.jpg)
ActiveSupport.on_load(:active_record) do
require 'newrelic_rpm'
NewRelic::Agent.after_fork( :force_reconnect => true) if defined?(Unicorn) # ...
newrelic.rb
![Page 75: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/75.jpg)
require 'shell' Shell.module_eval do include NewRelic::Agent:: MethodTracer add_method_tracer :system_multi end
newrelic.rb (Cont.)
![Page 76: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/76.jpg)
Cocaine::CommandLine.module_eval do include NewRelic::Agent:: MethodTracer add_method_tracer :run end
newrelic.rb (Cont.)
![Page 77: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/77.jpg)
Paperclip::Attachment.module_eval do include NewRelic::Agent:: MethodTracer add_method_tracer :url end
newrelic.rb (Cont.)
![Page 78: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/78.jpg)
require 'redis' Redis::Client.module_eval do include NewRelic::Agent:: MethodTracer add_method_tracer :process end
newrelic.rb (Cont.)
![Page 79: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/79.jpg)
require 'rest-core/engine/future/future'RC::Future.module_eval do include NewRelic::Agent::MethodTracer alias_method :yield_original, :yield def yield method = env[RC::REQUEST_METHOD] path = env[RC::REQUEST_PATH] # ...
newrelic.rb (Cont.)
![Page 80: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/80.jpg)
(Cont.)newrelic.rb def yield # ... metrics = ["External/#{path}/" \ "#{self.class.name}/#{method}", "External/#{path}/all", "External/all", "External/allWeb"] self.class. trace_execution_scoped metrics do yield_original end end
![Page 81: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/81.jpg)
•server.rb
•error.rb
•eagerload.rb
Ruby Codes(Cont.)
•newrelic.rb
•shell.rb
•waiter.rb
![Page 82: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/82.jpg)
shell.rbrequire 'waiter'require 'concurrency'module Shell module_function # this is for cocaine def call command, env={} Shell.system(*command) end # e.g. Shell.system('identify', 'img') def system *args system_multi(args).first end
![Page 83: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/83.jpg)
shell.rb# e.g. Shell.system_multi(%w[identify# image.png], %w[identify me.png])def system_multi *cmds if EM.reactor_running? # ... else cmds.map{ |cmd| system_blocking(cmd) } endend
(Cont.)
![Page 84: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/84.jpg)
shell.rbdef system_multi *cmds # ... w = Waiter.new r = {} cmds.each.with_index do |cmd, idx| system_async(*cmd) do |output| r[idx] = output w.resume(r.sort.map(&:last)) if r.size == cmds.size end end w.yield
(Cont.)
![Page 85: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/85.jpg)
shell.rbdef system_async *args tuple = system_spawn(args) Thread.new do begin result = system_wait(*tuple) rescue Exception => e EM.instance_variable_get( :@error_handler).call(e) ensure # ...ennnd
(Cont.)
![Page 86: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/86.jpg)
shell.rb
def system_async *args # ... if Concurrency::Model == Fiber EM.next_tick{ yield(result) } else yield(result) end
(Cont.)
![Page 87: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/87.jpg)
shell.rbdef system_spawn args err = if %w[test production]. include?(Rails.env) IO::NULL else Rails.logger.debug( "Shell: #{args.inspect}") $stderr end # ...
(Cont.)
![Page 88: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/88.jpg)
shell.rb
def system_spawn args # ... rd, wr = IO.pipe pid = Process.spawn(*args, :out => wr, :err => err) [pid, rd, wr]end
(Cont.)
![Page 89: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/89.jpg)
shell.rb
def system_wait pid, rd, wr wr.close result = rd.read Process.waitpid(pid) resultend
(Cont.)
![Page 90: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/90.jpg)
•server.rb
•error.rb
•eagerload.rb
Ruby Codes(Cont.)
•newrelic.rb
•shell.rb
•waiter.rb
![Page 91: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/91.jpg)
waiter.rbrequire 'thread'require 'fiber'
class Waiter def self.fiber_around? RC::RootFiber != Fiber.current && Thread.main == Thread.current endend
![Page 92: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/92.jpg)
waiter.rbclass Waiter def initialize if Waiter.fiber_around? @fiber = Fiber.current else @condv = ConditionVariable.new @mutex = Mutex.new end endend
(Cont.)
![Page 93: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/93.jpg)
waiter.rbclass Waiter def resume value if @fiber @fiber.resume(value) else @value = value @condv.broadcast end endend
(Cont.)
![Page 94: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/94.jpg)
waiter.rbclass Waiter def yield if @fiber Fiber.yield else @mutex.synchronize{ @condv.wait(@mutex) } @value end endend
(Cont.)
![Page 95: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/95.jpg)
•image_util.rb
•run_later.rb
•/search
•/create_and_share
Ruby Codes(Cont.) (Cont.)
![Page 96: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/96.jpg)
collage_web.rbclass CollageWeb < Collage extend ImageUtil
def self.create_from urls_or_url, fallback_urls=[] create(:image => merge_images( urls2images(urls_or_url, fallback_urls))) endend
![Page 97: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/97.jpg)
image_util.rbrequire 'tempfile'require 'shell'
module ImageUtil module_function def urls2files urls_or_url, fallback_urls=[] urls2images(urls_or_url, fallback_urls).map(&:file) endend
![Page 98: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/98.jpg)
image_util.rbmodule ImageUtil module_function def urls2images urls_or_url, fallback_urls=[] urls = [urls_or_url].flatten w = Waiter.new results = {} # ... w.yield.sort.map(&:last).compact endend
(Cont.)
![Page 99: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/99.jpg)
image_util.rbdef urls2images ...urls.zip([fallback_urls].flatten). each.with_index do |(url, fb), idx| ImageFile.from_url(url, fb) do |img| results[idx] = img w.resume(results) if results.size == urls.size end endw.yield.sort.map(&:last).compact
(Cont.)
![Page 100: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/100.jpg)
image_util.rbmodule ImageUtil module_function def merge_images images # ... end
ImageStruct = Struct.new(:width, :height, :file) class ImageFile < ImageStruct include ImageUtil # ...end
(Cont.)
![Page 101: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/101.jpg)
image_util.rb
module ImageUtil module_function def wget? @wget ||= !`which wget`.strip.empty? endend
(Cont.)
![Page 102: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/102.jpg)
image_util.rbmodule ImageUtil module_function def wget_command path, url if wget? ['wget', '-O', path, '--no-check-certificate', url] else ['curl', '-o', path, '--insecure' , url] end endend
(Cont.)
![Page 103: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/103.jpg)
image_util.rb def identify_command path ['identify', '-format', '%wx%h', path] end
def identify_result output if m = output.match(/(\d+)x(\d+)/) [m[1], m[2]].map(&:to_i) else nil end end
(Cont.)
![Page 104: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/104.jpg)
•image_util.rb
•run_later.rb
•/search
•/create_and_share
Ruby Codes(Cont.) (Cont.)
![Page 105: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/105.jpg)
run_later.rbrequire 'concurrency'module RunLater module_function def with if EM.reactor_running? EM.next_tick{ Concurrency.wrap{ yield } } else yield end endend
![Page 106: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/106.jpg)
•image_util.rb
•run_later.rb
•/search
•/create_and_share
Ruby Codes(Cont.) (Cont.)
![Page 107: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/107.jpg)
/searchget '/search' do params['q'].blank? && missing_arguments('q') # this raises
images, total = if limit == 0 [[], 0] else # ... end # ...end
![Page 108: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/108.jpg)
/searchcase params['engine']when 'pinterest'; sch_pinterestwhen 'pinterest_api'; sch_pinterest_apiwhen 'bing' ; sch_bing offset, limitwhen 'azure' ; sch_azure offset, limitwhen 'google'; sch_google offset, limitwhen 'flickr'; sch_flickr offset, limitelse ; sch_google offset, limit # default googleend
(Cont.)
![Page 109: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/109.jpg)
/search
render('search' => with_paging('total' => total, 'limit' => limit, 'offset' => offset, 'q' => params[:q], 'engine' => engine, 'data' => images))
(Cont.)
![Page 110: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/110.jpg)
/searchdef search_from_google offset, limit google = RC::GoogleImage.new( referer: request.url, userip: request.ip) search_image_and_flatten( google, offset, limit) do |q, n, i| google.search_image( q, rsz: n, start: i) endend
(Cont.)
![Page 111: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/111.jpg)
•image_util.rb
•run_later.rb
•/search
•/create_and_share
Ruby Codes(Cont.) (Cont.)
![Page 112: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/112.jpg)
/create_and_sharepost '/collages' do render_collage create_collageend
post '/collages/create_and_share' do render_collage create_collage{ |c| transfer "/collages/#{c.id}/share" }end
![Page 113: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/113.jpg)
/create_and_sharedef transfer path status, headers, body = jellyfish.call( env.merge('PATH_INFO' => path)) self.status status self.headers headers self.body bodyend
(Cont.)
![Page 114: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/114.jpg)
/create_and_sharedef create_collage &upload_callback para = params image = (para['image']||{})[:tempfile] plist = case para['plist'] when Hash; para['plist'][:tempfile] else ; para['plist'] end # ...
(Cont.)
![Page 115: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/115.jpg)
/create_and_share
if image # ...else missing_arguments('image')end
(Cont.)
![Page 116: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/116.jpg)
/create_and_sharec_para = params.merge('plist' => plist)c_para.delete('image')if rc_tumblr && for_auths_and_clients.empty? # no user for tumblrelse # check user for any other cases c_para['user'] = current_user_with_checkend
(Cont.)
![Page 117: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/117.jpg)
/create_and_share
c = Collage.create_with_params(c_para)# make paperclip happyimage.extend(OriginalFilename)image.original_filename = params['image'][:filename]c.save_image(image, &upload_callback)
(Cont.)
![Page 118: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/118.jpg)
/create_and_share
def save_image img, &block save_dimension img process_thumbnails img, &block selfend
(Cont.)
![Page 119: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/119.jpg)
(Cont.)/create_and_sharedef process_thumbnails img, &blk if blk RunLater.with do process_thumbnails_inplace img if blk.arity == 1; blk.call(self) else ; blk.call; end end else process_thumbnails_inplace img endend
![Page 120: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/120.jpg)
•crazy inspect
Miscellaneous Extras
![Page 121: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/121.jpg)
•crazy inspect
•who cares backtrace for 404
Miscellaneous Extras
![Page 122: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/122.jpg)
•crazy inspect
•who cares backtrace for 404
•assets pipeline and database connection
Miscellaneous Extras
![Page 123: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/123.jpg)
•crazy inspect
•who cares backtrace for 404
•assets pipeline and database connection
•fiber stack overflow
Miscellaneous Extras
![Page 124: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/124.jpg)
•crazy inspect
•who cares backtrace for 404
•assets pipeline and database connection
•fiber stack overflow
•fiber database connection pool
Miscellaneous Extras
![Page 125: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/125.jpg)
•crazy inspect
•who cares backtrace for 404
•assets pipeline and database connection
•fiber stack overflow
•fiber database connection pool
•thread-safe kaminari patch
Miscellaneous Extras
![Page 126: The Architecture of PicCollage Server](https://reader033.vdocument.in/reader033/viewer/2022052306/54005e258d7f724c088b4c96/html5/thumbnails/126.jpg)
Q?