Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
GuruSP - Solucionando o problema de Uploads em...
Search
Rafael Macedo
June 21, 2014
Programming
120
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
GuruSP - Solucionando o problema de Uploads em Apps no Heroku
Rafael Macedo
June 21, 2014
More Decks by Rafael Macedo
See All by Rafael Macedo
Modularização de código JS
macedorafael
0
250
TDC 2014 - Solucionando o problema de Uploads em Apps no Heroku
macedorafael
1
170
Aplicações Realtime com XMPP
macedorafael
3
220
Web in the cloud with ruby
macedorafael
2
400
Other Decks in Programming
See All in Programming
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
1
320
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
240
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
15
7.9k
Creating Composable Callables in Contemporary C++
rollbear
0
170
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
350k
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.6k
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
990
はてなアカウント基盤 State of the Union
cockscomb
1
1.1k
JavaDoc 再入門
nagise
1
430
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
610
AIで効率化できた業務・日常
ochtum
0
150
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
55
10k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.3k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
230
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.9k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
590
ラッコキーワード サービス紹介資料
rakko
1
3.8M
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
150
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
350
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
The Spectacular Lies of Maps
axbom
PRO
1
830
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Transcript
Solucionando o problema de Uploads em Apps no Heroku
@macedorafael http://github.com/macedo Rafael Macedo
@macedorafael http://github.com/macedo Macedo
backend…
…com chapéu de front
None
None
None
“O que pode dar errado num mero upload de uma
foto?”
None
30 segundos
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser
None
…
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
! ! ! ! Unicorn Rails AWS S3 Image Magick
Browser ! ! ! ! Resque/Sidekiq Worker
heroku addons
None
Blitline
Blitline Transloadit
Blitline Transloadit Cloudinary
Blitline Transloadit Cloudinary ✔
http://cloudinary.com
None
None
upload
None
•JPG, PNG, GIF, BMP, ICO, TIFF and PDF
•JPG, PNG, GIF, BMP, ICO, TIFF and PDF •Secure HTTP
upload API
•JPG, PNG, GIF, BMP, ICO, TIFF and PDF •Secure HTTP
upload API •Upload from your server or directly from the browser
storage
None
•Cloud-based persistent storage
•Cloud-based persistent storage •Highly available redundant storage
•Cloud-based persistent storage •Highly available redundant storage •S3
delivery
None
•Fast delivery (CDN)
•Fast delivery (CDN) •Smart caching
image transformation/ manipulation
None
resize
resize filter
resize filter crop
resize filter crop rotate
resize filter crop rotate face detection
resize filter crop rotate face detection chained transformation …
{"public_id"=>"fe23qemppmcorq0grmfv", "version"=>1403326723, "signature"=>"4e1a7bb2e3f3eb05eed25eed10cb09807561a764", "width"=>533, "height"=>300,
"format"=>"jpg", "resource_type"=>"image", "created_at"=>"2014-‐06-‐21T04:58:43Z", "bytes"=>13895, "type"=>"upload", "etag"=>"30b1c1b426db36b8e8c12d15d629fdb5", "url"=>"http://res.cloudinary.com/hxjx3jqm7/image/upload/v1403326723/ fe23qemppmcorq0grmfv.jpg", "secure_url"=>"https://res.cloudinary.com/hxjx3jqm7/image/upload/v1403326723/ fe23qemppmcorq0grmfv.jpg"}
{"public_id"=>"fe23qemppmcorq0grmfv", "version"=>1403326723, "signature"=>"4e1a7bb2e3f3eb05eed25eed10cb09807561a764", "width"=>533, "height"=>300,
"format"=>"jpg", "resource_type"=>"image", "created_at"=>"2014-‐06-‐21T04:58:43Z", "bytes"=>13895, "type"=>"upload", "etag"=>"30b1c1b426db36b8e8c12d15d629fdb5", "url"=>"http://res.cloudinary.com/hxjx3jqm7/image/upload/v1403326723/ fe23qemppmcorq0grmfv.jpg", "secure_url"=>"https://res.cloudinary.com/hxjx3jqm7/image/upload/v1403326723/ fe23qemppmcorq0grmfv.jpg"}
http://res.cloudinary.com/hxjx3jqm7/image/ upload/v1403326723/ fe23qemppmcorq0grmfv.jpg
http://res.cloudinary.com/hxjx3jqm7/image/ upload/v1403326723/ fe23qemppmcorq0grmfv.jpg
http://res.cloudinary.com/hxjx3jqm7/image/ upload/v1403326723/ fe23qemppmcorq0grmfv.jpg http://res.cloudinary.com/hxjx3jqm7/image/ upload/w_160,h_160,c_thumb,g_face/ fe23qemppmcorq0grmfv.jpg
http://res.cloudinary.com/hxjx3jqm7/image/ upload/v1403326723/ fe23qemppmcorq0grmfv.jpg http://res.cloudinary.com/hxjx3jqm7/image/ upload/w_160,h_160,c_thumb,g_face/ fe23qemppmcorq0grmfv.jpg
None
gem 'cloudinary'
# config/cloudinary.yml development: cloud_name:
“sample” api_key: “912739217312873” api_secret: “a123=asdaszad34dsf”
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
width: 160, height: 160, crop: fill, effect: ”sepia” )
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
effect: )
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
width: 100, height: 150, effect: :pixelate)
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
cl_image_tag(“e23qemppmcorq0grmfv.jpg”,
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class ImageUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave
version :standard do process :resize_to_fill => [100, 150, :fill] cloudinary_transformation quality: 80 end version :thumbnail do process :eager => true cloudinary_transformation transformation: [ { width: 100, height: 100, crop: :thumb, gravity: :face }, { overlay: ”watermark”, width: 30, hgravity: :south_east, x: 5, y: 5 } ] end end
class Advertisement < ActiveRecord::Base ... mount_uploader
:image, ImageUploader ... end
= form_for(:advertisement) do |f| = f.hidden_field(:image_cache)
= f.file_field(:image)
None
# app/assets/javascripts/application.js //= require cloudinary
= form_for(:advertisement) do |f| ...
= cloudinary_js_config = f.cl_image_upload(:image) ..
= form_for(:advertisement) do |f| ...
= cloudinary_js_config = f.cl_image_upload(:image) ..
= form_for(:advertisement) do |f| ...
= cloudinary_js_config = f.cl_image_upload(:image) ..
None
$$$
None
10 GB Storage
10 GB Storage 40 GB Bandwidth
Cloudinary
$35
S3
$7
None
None
$7
$42
Conclusão
“O que pode dar errado num mero upload de uma
foto?”
Muita coisa!
None
Processamento background
Processamento background Direct Upload
None
OBRIGADO
OBRIGADO ?