class SmartS3Sync::FileTarget
Attributes
destinations[R]
digest[R]
local_source[R]
remote_filename[R]
size[R]
Public Class Methods
new(digest, remote_filename, size)
click to toggle source
# File lib/smart_s3_sync/file_target.rb, line 8 def initialize(digest, remote_filename, size) @digest = digest @size = size @remote_filename = remote_filename @local_source = nil @destinations = [] end
Public Instance Methods
add_destination(file)
click to toggle source
# File lib/smart_s3_sync/file_target.rb, line 16 def add_destination(file) unless destinations.include?(file) # If we already have a local file with the right checksum, # we don't add it to the list of destinations and instead # mark it as a local source. if File.exists?(file) && file_hash(file) == digest.to_s add_local_source(file) else destinations.push(file) end end end
copy!(fog_dir, sync_options={})
click to toggle source
# File lib/smart_s3_sync/file_target.rb, line 29 def copy!(fog_dir, sync_options={}) # If every copy in the cloud is already present, the # number of destinations will be 0 - there is no work # left to do. if destinations.length > 0 if local_source.nil? # we prefer to not have to download copy_from_fog(fog_dir, sync_options) else copy_from_local(local_source, sync_options) end end end
Private Instance Methods
add_local_source(file)
click to toggle source
# File lib/smart_s3_sync/file_target.rb, line 80 def add_local_source(file) if local_source.nil? @local_source = file else FileUtils.ln(local_source, file, :force => true) end end
copy_from_fog(fog_dir, sync_options={})
click to toggle source
# File lib/smart_s3_sync/file_target.rb, line 44 def copy_from_fog(fog_dir, sync_options={}) $stderr.puts "Downloading #{remote_filename}" tries = 0 file = nil begin file = download(fog_dir, sync_options) # basically, just try. if file_hash(file.path) != digest.to_s raise "Hash mismatch downloading #{remote_filename}" end copy_from_local(file.path, sync_options) # with a copy locally, the job is the same @local_source = destinations.shift # we now have a local copy! rescue StandardError => e if tries < 5 tries += 1 $stderr.puts e $stderr.puts "retrying" retry else raise e end ensure file.close(true) unless file.nil? end end
copy_from_local(source, sync_options={})
click to toggle source
# File lib/smart_s3_sync/file_target.rb, line 71 def copy_from_local(source, sync_options={}) $stderr.puts "Linking #{destinations.join(', ')}" destinations.each do |dest| FileUtils.mkdir_p(File.dirname(dest), :mode => 0755) FileUtils.ln(source, dest, :force => true) DigestCache.save_record(dest, File.mtime(dest).to_i, digest.to_s) end end
download(fog_dir, sync_options={})
click to toggle source
# File lib/smart_s3_sync/file_target.rb, line 92 def download(fog_dir, sync_options={}) dir = File.dirname(destinations[0]) FileUtils.mkdir_p(dir) Tempfile.new(".#{digest}", dir).tap do |file| rfile = fog_dir.files.get(remote_filename) do |chunk, left, total| if (chunk.size + left == total) # fog might restart in the middle file.rewind end file.write chunk end file.close File.chmod(0644, file.path) if sync_options.has_key?('set-timestamp-from-metadata') time = rfile.metadata[sync_options['set-timestamp-from-metadata']] time &&= Time.at(time.to_i) time && File.utime(time, time, file) end end end
file_hash(path)
click to toggle source
# File lib/smart_s3_sync/file_target.rb, line 88 def file_hash(path) DigestCache.digest(path) end