Class: Yob::Store::AWS

Inherits:
Object
  • Object
show all
Defined in:
lib/yob/store.rb

Constant Summary collapse

BLOCK_SIZE =

must be at least 5 MB

1048576 * 5

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ AWS

Returns a new instance of AWS.



7
8
9
10
11
12
13
14
# File 'lib/yob/store.rb', line 7

def initialize(configuration)
  require 'aws-sdk'

  @configuration = configuration

  ::AWS.config(:access_key_id     => configuration.aws_access_key_id,
               :secret_access_key => configuration.aws_secret_access_key)
end

Instance Attribute Details

#pidObject (readonly)

Returns the value of attribute pid.



5
6
7
# File 'lib/yob/store.rb', line 5

def pid
  @pid
end

Instance Method Details

#storage_input_pipe(filename) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/yob/store.rb', line 16

def storage_input_pipe(filename)
  rd, wr = IO.pipe
  @pid = fork do
    $0 = "yob: AWS S3 storage"
    wr.close
    store(filename, rd)
    rd.close
  end
  rd.close
  wr
end

#store(filename, file_handle) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/yob/store.rb', line 28

def store(filename, file_handle)
  puts "[Store::AWS] uploading #{filename}"
  object = s3_bucket.objects["#{@configuration["aws_filename_prefix"]}#{filename}"]

  data = file_handle.read(BLOCK_SIZE)
  if data.nil? || data.length == 0
    print "[Store::AWS] no file data received, upload aborted"
    return
  end

  # If the entire file is less than BLOCK_SIZE, send it in one hit.
  # Otherwise use AWS's multipart upload feature.  Note that each part must be at least 5MB.
  if data.length < BLOCK_SIZE
    object.write(data)
  else
    upload = object.multipart_uploads.create
    begin
      print "[Store::AWS] multipart upload started\n" if @configuration["debug"]
      bytes = 0
      while data && data.length > 0
        upload.add_part(data)
        bytes += data.length
        print "[Store::AWS] #{bytes} bytes sent\n" if @configuration["debug"]
        data = file_handle.read(BLOCK_SIZE)
      end
      upload.close
    rescue
      upload.abort
      raise
    end
  end

  if grant_to = @configuration["aws_grant_access_to"]
    puts "[Store::AWS] granting access to #{filename}"
    object.acl = access_control_list(grant_to)
  end

  puts "[Store::AWS] uploaded"
end