views:

66

answers:

2

I am getting a AWS::S3::NoConnectionEstablished exception when trying to download a file using paperclip + s3. I can fire up s3sh and create a connection just fine with the s3 credentials in my config. What is the best next step I can take to debug this issue? This is what my model looks like:

has_attached_file :file,
                    :storage => :s3,
                    :s3_permssions => :private,
                    :path => lambda { |attachment| ":id_partition/:basename.:extension" },
                    :url => lambda { |attachment| "products/:id/:basename.:extension" },
                    :s3_credentials => "#{Rails.root}/config/amazon_s3.yml",
                    :bucket => "products.mycompany.com"

And the error occurs here:

def temporary_s3_url(options={})
    options.reverse_merge! :expires_in => 10.minutes #, :use_ssl => true
    hard_url = AWS::S3::S3Object.url_for file.path, file.options[:bucket], options
    # Use our vanity URL
 hard_url.gsub("http://s3.amazonaws.com/products.mycompany.com","http://products.mycompany.com")
  end

I tried hard coding a connection as the first line in the temporary_s3_url method but I get a "bucket not found" error. I think the problem is definitely that paperclip is having a problem initializing my s3 configuration.

A: 

I have paperclip with S3 and Heroku on two apps. This is what worked for me:

In your mode:

has_attached_file :image, 
   :styles => {  :thumb => "250x250>" },
   :storage => :s3, :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
   :path => "username/:attachment/:style/:id.:extension"

in config/s3.yml

development:
  bucket: name
  access_key_id: xyz
  secret_access_key: xyz

test:
  bucket: name
  access_key_id: xyz
  secret_access_key: xyz

production:
  bucket: name
  access_key_id: xyz
  secret_access_key: xyz

and of course in your environment.rb you need to have the gem included or however you include gems.

Sam
A: 

Remember that storing to S3 is not dependable--the connection can be lost, the store fail before completing, etc.

I created my own library routines that attempt to do the store, but catch various errors. For the no connection error, I reconnect. For other storage errors, I retry (up to three times). You may also want to wait a second between retries.

Added

Below is the library routine I use for AWS calls.

You'd need to add/modify the rescue clauses to catch the errors that you're experiencing. Your connection_reset and error reporting methods will also be specific to your sw.

# Usage example:
# aws_repeat("Storing #{bucket}/#{obj}"){
#   AWS::S3::S3Object.store(obj, data, bucket, opt)}    

def aws_repeat(description = nil)
  # Calls the block up to 3 times, allowing for AWS connection reset problems
  for i in 1..3
    begin
      yield
    rescue Errno::ECONNRESET => e
      ok = false
      ActiveRecord::Base.logger.error \
           "AWS::S3 *** Errno::ECONNRESET => sleeping"
      sleep(1)
      if i == 1
        # reset connection
        connect_to_aws # re-login in to AWS
        ActiveRecord::Base.logger.error \
           "AWS::S3 *** Errno::ECONNRESET => reset connection"
      end        
    else
      ok = true
      break
    end
  end

  unless ok
    msg = "AWS::S3 *** FAILURE #{description.to_s}"
    ActiveRecord::Base.logger.error msg
    security_log(msg)
  end

  ok
end

############################################
############################################

def connect_to_aws
  # load params. Cache at class (app) level 
  @@s3_config_path ||= RAILS_ROOT + '/config/amazon_s3.yml'
  @@s3_config ||= 
       YAML.load_file(@@s3_config_path)[ENV['RAILS_ENV']].symbolize_keys

  AWS::S3::Base.establish_connection!(
    :access_key_id     => @@s3_config[:access_key_id],
    :secret_access_key => @@s3_config[:secret_access_key],
    :server            => @@s3_config[:server],
    :port              => @@s3_config[:port],
    :use_ssl           => @@s3_config[:use_ssl],
    :persistent        => false # from http://www.ruby-forum.com/topic/110842
    )

  true 
end
Larry K
Sounds cool but this completely stopped working so I know it's not a hiccup. IS your library open source? Would be great to check it out.
Bill Brasky
It's not much of a library, see amended answer.
Larry K