Skip to content

Commit

Permalink
Improved Serving Remotely docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Evans committed Jan 5, 2012
1 parent 0b43d5a commit 3f8a198
Showing 1 changed file with 41 additions and 20 deletions.
61 changes: 41 additions & 20 deletions extra_docs/ServingRemotely.md
Expand Up @@ -10,8 +10,8 @@ For most cases, this is the way to go - you have control over it and you can {fi
However, if for whatever reason you must serve content from the datastore directly, e.g. for lightening the load on your server, Dragonfly
provides a number of ways of doing this.

Serving Original Content
------------------------
Original Content
----------------
The {file:DataStorage#File\_datastore FileDataStore}, {file:DataStorage#S3\_datastore S3DataStore} and
{file:DataStorage#Couch\_datastore CouchDataStore} allow for serving data directly, so given a Dragonfly app

Expand All @@ -27,45 +27,66 @@ we can get the remote url using

or from a model attachment:

my_model.attachment.remote_url # http://my-bucket.s....
my_model.attachment.remote_url # http://my-bucket.s3.amazonaws.com/2011...

Serving Processed Content
-------------------------
Processed Content
-----------------
If using models, the quick and easy way to serve e.g. image thumbnails remotely is to process them _on upload_
like most other attachment ruby gems (see {file:Models#Up-front_thumbnailing}),
e.g. for my avatar model,

class Avatar
image_accessor :image do
copy_to(:small_image){|a| a.thumb('200x200#') }
end
image_accessor :small_image
end

Then we can use `remote_url` for for each accessor.

avatar.image.remote_url # http://my-bucket.s3.amazonaws.com/some/path.jpg
avatar.small_image.remote_url # http://my-bucket.s3.amazonaws.com/some/other/path.jpg

However, this has all the limitations that come with up-front processing, such as having to regenerate the thumbnail when the size requirement changes.

Serving Processed Content *on-the-fly*
--------------------------------------
Serving processed versions of content such as thumbnails remotely is a bit more tricky as we need to upload the thumbnail
to the datastore in the on-the-fly manner.

Dragonfly provides a way of doing this using `define_url` and `before_serve` methods.

The details of keeping track of/expiring these thumbnails is up to you.

Below is an example using an ActiveRecord 'Thumb' table to keep track of image thumbnails.
We need to keep track of which thumbnails have been already created, by storing a uid for each one.
Below is an example using an ActiveRecord 'Thumb' table to keep track of already created thumbnail uids.
It has two string columns; 'job' and 'uid'.

app.configure do |c|

c.server.before_serve do |job, env|
# Before serving, the first time it is requested...
# store the thumbnail in the datastore
uid = job.store
# Keep track of its uid
Thumb.create!(
:uid => uid,
:job => job.serialize # 'BAhbBls...' - holds all the job info
) # e.g. fetch 'some_uid' then resize to '40x40'
end

# Override the .url method...
c.define_url do |app, job, opts|
thumb = Thumb.find_by_job(job.serialize)
# If (fetch 'some_uid' then resize to '40x40') has been stored already..
# If (fetch 'some_uid' then resize to '40x40') has been stored already, give the datastore's remote url ...
if thumb
app.datastore.url_for(thumb.uid)
# ...otherwise serve from the Dragonfly server as per usual
# ...otherwise give the local Dragonfly server url
else
app.server.url_for(job)
end
end

# Before serving from the local Dragonfly server...
c.server.before_serve do |job, env|
# ...store the thumbnail in the datastore...
uid = job.store
# ...keep track of its uid so next time we can serve directly from the datastore
Thumb.create!(
:uid => uid,
:job => job.serialize # 'BAhbBls...' - holds all the job info
) # e.g. fetch 'some_uid' then resize to '40x40'
end

end

Expand Down

0 comments on commit 3f8a198

Please sign in to comment.