mir 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +6 -0
- data/README.md +2 -1
- data/lib/mir/application.rb +35 -19
- data/lib/mir/config.rb +11 -2
- data/lib/mir/models/resource.rb +1 -1
- data/lib/mir/utils.rb +1 -0
- data/lib/mir/version.rb +1 -1
- metadata +3 -2
data/CHANGELOG.md
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
# Mir Changelog
|
2
|
+
|
3
|
+
### 0.1.4
|
4
|
+
|
5
|
+
* Fixed bug that occurred during pull operations when the connection with Amazon S3 is interrupted mid-transmission. Pull operations will now continue to download an asset from S3 until the checksum matches what has been stored in the local index
|
6
|
+
* Added configuration option max_download_attempts to allow the user to set the maximum number of pull attempts per file
|
data/README.md
CHANGED
@@ -16,7 +16,8 @@ The inspiration for this tool is to provide similar functionality to the classic
|
|
16
16
|
Mir uses a YAML file for configuration settings. Unless you specify otherwise, Mir will look for the file 'mir_settings.yml' in the HOME and /etc/mir directories.
|
17
17
|
|
18
18
|
settings:
|
19
|
-
|
19
|
+
max_upload_attempts: 5
|
20
|
+
max_download_attempts: 5
|
20
21
|
max_threads: 5
|
21
22
|
cloud_provider:
|
22
23
|
type: s3
|
data/lib/mir/application.rb
CHANGED
@@ -7,7 +7,7 @@ module Mir
|
|
7
7
|
class Application
|
8
8
|
|
9
9
|
DEFAULT_SETTINGS_FILE_NAME = "mir_settings.yml"
|
10
|
-
DEFAULT_BATCH_SIZE =
|
10
|
+
DEFAULT_BATCH_SIZE = 100
|
11
11
|
|
12
12
|
# Creates a new Mir instance
|
13
13
|
def self.start
|
@@ -146,37 +146,53 @@ module Mir
|
|
146
146
|
|
147
147
|
# Copy the remote disk contents into the specified directory
|
148
148
|
def pull(target)
|
149
|
-
Utils.try_create_dir(target)
|
150
|
-
write_dir = Dir.new(target)
|
149
|
+
write_dir = Utils.try_create_dir(target)
|
151
150
|
Mir.logger.info "Copying remote disk to #{write_dir.path} using #{config.max_threads} threads"
|
151
|
+
failed_downloads = []
|
152
152
|
|
153
153
|
time = Benchmark.measure do
|
154
154
|
queue = WorkQueue.new(config.max_threads)
|
155
|
-
|
156
|
-
# loop through each resource. If the resource is a directory, create the path
|
157
|
-
# otherwise download the file
|
155
|
+
|
158
156
|
Models::Resource.ordered_groups(DEFAULT_BATCH_SIZE) do |resources|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
157
|
+
# Track the number of download attempts made per resource
|
158
|
+
batch = resources.inject({}) { |set, resource| set[resource] = 0; set }
|
159
|
+
|
160
|
+
while !batch.empty? do
|
161
|
+
batch.each do |resource, attempts|
|
162
|
+
dest = File.join(write_dir.path, resource.filename)
|
163
|
+
if resource.is_directory?
|
164
|
+
Utils.try_create_dir(dest)
|
165
|
+
batch.delete(resource)
|
166
|
+
elsif attempts >= config.max_download_attempts
|
167
|
+
Mir.logger.info "Resource #{resource.abs_path} failed to download"
|
168
|
+
failed_downloads << resource
|
169
|
+
batch.delete(resource)
|
170
|
+
elsif resource.synchronized? dest
|
171
|
+
Mir.logger.debug "Skipping already downloaded file #{resource.abs_path}"
|
172
|
+
batch.delete(resource)
|
173
|
+
else
|
174
|
+
batch[resource] += 1
|
175
|
+
queue.enqueue_b do
|
176
|
+
Mir.logger.debug "Beginning download of #{resource.abs_path}"
|
177
|
+
disk.copy(resource.abs_path, dest)
|
178
|
+
if resource.synchronized? dest
|
179
|
+
FileUtils.chmod_R 0755, dest # allow binaries to execute
|
180
|
+
puts "Pulled #{dest}"
|
181
|
+
batch.delete(resource)
|
182
|
+
end
|
171
183
|
end
|
172
184
|
end
|
173
185
|
end
|
186
|
+
queue.join
|
174
187
|
end
|
175
|
-
queue.join
|
176
188
|
end
|
177
189
|
end
|
178
190
|
Mir.logger.info time
|
179
191
|
puts "Completed pull operation #{time}"
|
192
|
+
unless failed_downloads.empty?
|
193
|
+
puts "The following files failed to download after several attempts:\n}"
|
194
|
+
puts failed_downloads.join("\n")
|
195
|
+
end
|
180
196
|
end
|
181
197
|
|
182
198
|
end
|
data/lib/mir/config.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
1
|
# The config class is used for storage of user settings and preferences releated to
|
4
2
|
# S3 storage
|
5
3
|
module Mir
|
@@ -10,9 +8,20 @@ module Mir
|
|
10
8
|
def initialize(config_file = nil)
|
11
9
|
@config_file = config_file
|
12
10
|
@settings, @database = nil, nil
|
11
|
+
|
12
|
+
self.max_upload_attempts = 10
|
13
|
+
self.max_download_attempts = 10
|
14
|
+
self.max_threads = 5
|
15
|
+
|
16
|
+
yield self if block_given?
|
13
17
|
end
|
14
18
|
|
19
|
+
attr_accessor :max_upload_attempts, :max_download_attempts, :max_threads
|
20
|
+
|
15
21
|
# Validates configuration settings
|
22
|
+
# TODO: move this into a class method responsible for parsing the YAML file. We
|
23
|
+
# shouldn't have to explicitly check for a valid object unless the user has provided
|
24
|
+
# a settings file
|
16
25
|
def valid?
|
17
26
|
if @config_file.nil? or !File.exist?(@config_file)
|
18
27
|
Mir.logger.error("Configuration file not found")
|
data/lib/mir/models/resource.rb
CHANGED
@@ -101,7 +101,7 @@ module Mir
|
|
101
101
|
|
102
102
|
def update_failure
|
103
103
|
num_times_failed = times_failed + 1
|
104
|
-
will_requeue = (num_times_failed < Mir::Application.config.
|
104
|
+
will_requeue = (num_times_failed < Mir::Application.config.max_upload_attempts)
|
105
105
|
update_attributes :times_failed => num_times_failed, :in_progress => false, :queued => will_requeue
|
106
106
|
end
|
107
107
|
|
data/lib/mir/utils.rb
CHANGED
data/lib/mir/version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: mir
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.1.
|
5
|
+
version: 0.1.4
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Nate Miller
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-09-
|
13
|
+
date: 2011-09-23 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -90,6 +90,7 @@ extra_rdoc_files: []
|
|
90
90
|
|
91
91
|
files:
|
92
92
|
- .gitignore
|
93
|
+
- CHANGELOG.md
|
93
94
|
- Gemfile
|
94
95
|
- LICENSE
|
95
96
|
- README.md
|