miga-base 0.7.16.0 → 0.7.16.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/miga +2 -1
- data/lib/miga/cli/action/doctor.rb +57 -21
- data/lib/miga/cli/action/doctor/base.rb +13 -4
- data/lib/miga/cli/action/get.rb +2 -2
- data/lib/miga/cli/action/get_db.rb +1 -1
- data/lib/miga/cli/action/run.rb +4 -1
- data/lib/miga/cli/opt_helper.rb +5 -4
- data/lib/miga/common.rb +38 -4
- data/lib/miga/daemon/base.rb +1 -0
- data/lib/miga/json.rb +17 -5
- data/lib/miga/version.rb +2 -2
- data/scripts/project_stats.bash +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fcd30efdaa8cf3a8ae87b5cc658363c2d37c0beb3c13491595beb983b1629b32
|
4
|
+
data.tar.gz: '0441764548f4199a8f3df253c151dc856aa414f5a91d02126bcb893ee2fe6835'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18e829f1cb4141df9515565bd19af32e67b9920689a75dd4b5f2f5a79d0a5b7d86ea425f64e7702766e09a14c5b70af4d07ccb16df94aeef3ba4ade54e9506ab
|
7
|
+
data.tar.gz: 72ad22fd3386214825c463edc9232f2deeae24d06257a523f73592fd2d9496e452d192d10f37cf493b52a936578c3111a1a8801a78494688d51fc75b01e489f2
|
data/bin/miga
CHANGED
@@ -7,6 +7,7 @@ class MiGA::Cli::Action::Doctor < MiGA::Cli::Action
|
|
7
7
|
include MiGA::Cli::Action::Doctor::Base
|
8
8
|
|
9
9
|
def parse_cli
|
10
|
+
cli.defaults = { threads: 1 }
|
10
11
|
cli.defaults = Hash[@@OPERATIONS.keys.map { |i| [i, true] }]
|
11
12
|
cli.parse do |opt|
|
12
13
|
operation_n = Hash[@@OPERATIONS.map { |k, v| [v[0], k] }]
|
@@ -24,6 +25,10 @@ class MiGA::Cli::Action::Doctor < MiGA::Cli::Action
|
|
24
25
|
@@OPERATIONS.each_key { |i| cli[i] = false }
|
25
26
|
cli[op_k] = true
|
26
27
|
end
|
28
|
+
opt.on(
|
29
|
+
'-t', '--threads INT', Integer,
|
30
|
+
"Concurrent threads to use. By default: #{cli[:threads]}"
|
31
|
+
) { |v| cli[:threads] = v }
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
@@ -59,11 +64,19 @@ class MiGA::Cli::Action::Doctor < MiGA::Cli::Action
|
|
59
64
|
# Perform status operation with MiGA::Cli +cli+
|
60
65
|
def check_status(cli)
|
61
66
|
cli.say 'Updating metadata status'
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
67
|
+
p = cli.load_project
|
68
|
+
n = p.dataset_names.size
|
69
|
+
(0 .. cli[:threads] - 1).map do |i|
|
70
|
+
Process.fork do
|
71
|
+
k = 0
|
72
|
+
cli.load_project.each_dataset do |d|
|
73
|
+
k += 1
|
74
|
+
cli.advance('Datasets:', k, n, false) if i == 0
|
75
|
+
d.recalculate_status if k % cli[:threads] == i
|
76
|
+
end
|
77
|
+
end
|
66
78
|
end
|
79
|
+
Process.waitall
|
67
80
|
cli.say
|
68
81
|
end
|
69
82
|
|
@@ -71,36 +84,59 @@ class MiGA::Cli::Action::Doctor < MiGA::Cli::Action
|
|
71
84
|
# Perform databases operation with MiGA::Cli +cli+
|
72
85
|
def check_db(cli)
|
73
86
|
cli.say 'Checking integrity of databases'
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
87
|
+
p = cli.load_project
|
88
|
+
n = p.dataset_names.size
|
89
|
+
(0 .. cli[:threads] - 1).map do |i|
|
90
|
+
Process.fork do
|
91
|
+
k = 0
|
92
|
+
p.each_dataset do |d|
|
93
|
+
k += 1
|
94
|
+
cli.advance('Datasets:', k, n, false) if i == 0
|
95
|
+
next unless k % cli[:threads] == i
|
96
|
+
each_database_file(d) do |db_file, metric, result|
|
97
|
+
check_sqlite3_database(db_file, metric) do
|
98
|
+
cli.say(
|
99
|
+
" > Removing malformed database from #{d.name}:#{result} "
|
100
|
+
)
|
101
|
+
File.unlink(db_file)
|
102
|
+
r = d.result(result) or next
|
103
|
+
[r.path(:done), r.path].each do |f|
|
104
|
+
File.unlink(f) if File.exist?(f)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
83
108
|
end
|
84
109
|
end
|
85
110
|
end
|
111
|
+
Process.waitall
|
86
112
|
cli.say
|
87
113
|
end
|
88
114
|
|
89
115
|
##
|
90
116
|
# Perform bidirectional operation with MiGA::Cli +cli+
|
91
117
|
def check_bidir(cli)
|
92
|
-
cli.say 'Checking
|
118
|
+
cli.say 'Checking if reference distances are bidirectional'
|
93
119
|
ref_ds = cli.load_project.each_dataset.select(&:ref?)
|
94
120
|
ref_names = ref_ds.map(&:name)
|
95
|
-
n
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
121
|
+
n = ref_ds.size
|
122
|
+
(0 .. cli[:threads] - 1).map do |i|
|
123
|
+
Process.fork do
|
124
|
+
k = 0
|
125
|
+
ref_ds.each do |d|
|
126
|
+
k += 1
|
127
|
+
cli.advance('Datasets:', k, n, false) if i == 0
|
128
|
+
next unless k % cli[:threads] == i
|
100
129
|
|
101
|
-
|
102
|
-
|
130
|
+
saved = saved_targets(d)
|
131
|
+
next if saved.nil?
|
132
|
+
|
133
|
+
(ref_names - saved).each do |k|
|
134
|
+
save_bidirectional(cli.load_project.dataset(k), d)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
103
138
|
end
|
139
|
+
Process.waitall
|
104
140
|
cli.say
|
105
141
|
end
|
106
142
|
|
@@ -134,10 +134,19 @@ module MiGA::Cli::Action::Doctor::Base
|
|
134
134
|
|
135
135
|
data[0], data[1] = data[1], data[0]
|
136
136
|
SQLite3::Database.new(db_file_b) do |conn|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
137
|
+
attempts = 0
|
138
|
+
begin
|
139
|
+
attempts += 1
|
140
|
+
conn.execute(
|
141
|
+
"insert into #{metric} (seq1, seq2, #{metric}, sd, n, omega) " +
|
142
|
+
"values(?, ?, ?, ?, ?, ?)", data
|
143
|
+
)
|
144
|
+
rescue SQLite3::BusyException => e
|
145
|
+
raise "Cannot populate #{db_file_b}: #{e.message}" if attempts > 3
|
146
|
+
|
147
|
+
sleep(1)
|
148
|
+
retry
|
149
|
+
end
|
141
150
|
end
|
142
151
|
end
|
143
152
|
end
|
data/lib/miga/cli/action/get.rb
CHANGED
@@ -70,7 +70,7 @@ class MiGA::Cli::Action::Get < MiGA::Cli::Action
|
|
70
70
|
glob = get_sub_cli
|
71
71
|
p = cli.load_project
|
72
72
|
glob.each do |sub_cli|
|
73
|
-
rd = create_remote_dataset(sub_cli)
|
73
|
+
rd = create_remote_dataset(sub_cli, p)
|
74
74
|
next if rd.nil?
|
75
75
|
|
76
76
|
if sub_cli[:get_md]
|
@@ -115,7 +115,7 @@ class MiGA::Cli::Action::Get < MiGA::Cli::Action
|
|
115
115
|
glob
|
116
116
|
end
|
117
117
|
|
118
|
-
def create_remote_dataset(sub_cli)
|
118
|
+
def create_remote_dataset(sub_cli, p)
|
119
119
|
sub_cli.ensure_par(dataset: '-D', ids: '-I')
|
120
120
|
unless sub_cli[:api_key].nil?
|
121
121
|
ENV["#{sub_cli[:universe].to_s.upcase}_API_KEY"] = sub_cli[:api_key]
|
@@ -165,7 +165,7 @@ class MiGA::Cli::Action::GetDb < MiGA::Cli::Action
|
|
165
165
|
def check_target
|
166
166
|
return false if cli[:overwrite]
|
167
167
|
|
168
|
-
file = File.expand_path(cli[:database], cli[:local])
|
168
|
+
file = File.expand_path(cli[:database].to_s, cli[:local])
|
169
169
|
if Dir.exist? file
|
170
170
|
warn "The target directory already exists: #{file}"
|
171
171
|
true
|
data/lib/miga/cli/action/run.rb
CHANGED
@@ -8,7 +8,7 @@ class MiGA::Cli::Action::Run < MiGA::Cli::Action
|
|
8
8
|
def parse_cli
|
9
9
|
cli.defaults = { try_load: false, thr: 1, env: false }
|
10
10
|
cli.parse do |opt|
|
11
|
-
cli.opt_object(opt, [:project, :dataset_opt, :
|
11
|
+
cli.opt_object(opt, [:project, :dataset_opt, :result_opt])
|
12
12
|
opt.on(
|
13
13
|
'-t', '--threads INT', Integer,
|
14
14
|
"Threads to use in the local run (by default: #{cli[:thr]})"
|
@@ -43,6 +43,9 @@ class MiGA::Cli::Action::Run < MiGA::Cli::Action
|
|
43
43
|
cli[:dataset] = nil
|
44
44
|
end
|
45
45
|
|
46
|
+
# Use virtual result if not explicitly passed
|
47
|
+
cli[:result] ||= cli[:dataset] ? :d : :p
|
48
|
+
|
46
49
|
# Load project
|
47
50
|
p = cli.load_project
|
48
51
|
|
data/lib/miga/cli/opt_helper.rb
CHANGED
@@ -56,10 +56,11 @@ module MiGA::Cli::OptHelper
|
|
56
56
|
# - :project_type To allow (optionally) a type of project
|
57
57
|
# - :project_type_req To require a type of project
|
58
58
|
# - :result To require a type of project or dataset result
|
59
|
+
# - :result_opt To allow (optionally) a type of result
|
59
60
|
# - :result_dataset To require a type of dataset result
|
60
61
|
# - :result_project To require a type of project result
|
61
|
-
# The options :result, :result_dataset, and :result_project
|
62
|
-
# exclusive
|
62
|
+
# The options :result, :result_opt, :result_dataset, and :result_project
|
63
|
+
# are mutually exclusive
|
63
64
|
def opt_object(opt, what = [:project, :dataset])
|
64
65
|
what.each do |w|
|
65
66
|
case w
|
@@ -82,10 +83,10 @@ module MiGA::Cli::OptHelper
|
|
82
83
|
"#{req}Type of #{obj}. Recognized types include:",
|
83
84
|
*klass.KNOWN_TYPES.map { |k, v| "~ #{k}: #{v[:description]}" }
|
84
85
|
) { |v| self[:type] = v.downcase.to_sym }
|
85
|
-
when :result
|
86
|
+
when :result, :result_opt
|
86
87
|
opt.on(
|
87
88
|
'-r', '--result STRING',
|
88
|
-
|
89
|
+
"#{"(Mandatory) " if w == :result}Name of the result",
|
89
90
|
'Recognized names for dataset-specific results include:',
|
90
91
|
*MiGA::Dataset.RESULT_DIRS.keys.map { |n| " ~ #{n}" },
|
91
92
|
'Recognized names for project-wide results include:',
|
data/lib/miga/common.rb
CHANGED
@@ -52,10 +52,44 @@ class MiGA::MiGA
|
|
52
52
|
# 1,000 otherwise.
|
53
53
|
# The report goes to $stderr iff --verborse
|
54
54
|
def advance(step, n = 0, total = nil, bin = true)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
# Initialize advance timing
|
56
|
+
@_advance_time ||= { last: nil, n: 0, avg: nil }
|
57
|
+
if n <= 1 || @_advance_time[:n] > n
|
58
|
+
@_advance_time[:last] = nil
|
59
|
+
@_advance_time[:n] = 0
|
60
|
+
@_advance_time[:avg] = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
# Estimate timing
|
64
|
+
adv_n = n - @_advance_time[:n]
|
65
|
+
unless total.nil? || @_advance_time[:last].nil? || adv_n <= 0
|
66
|
+
if adv_n.to_f/n > 0.001
|
67
|
+
this_time = Time.now - @_advance_time[:last]
|
68
|
+
this_avg = this_time / adv_n
|
69
|
+
@_advance_time[:avg] ||= this_avg
|
70
|
+
@_advance_time[:avg] = 0.9 * @_advance_time[:avg] + 0.1 * this_avg
|
71
|
+
end
|
72
|
+
end
|
73
|
+
@_advance_time[:last] = Time.now
|
74
|
+
@_advance_time[:n] = n
|
75
|
+
|
76
|
+
# Report
|
77
|
+
adv_vals = [100.0 * n / total, num_suffix(n, bin), num_suffix(total, bin)]
|
78
|
+
adv =
|
79
|
+
total.nil? ? (n == 0 ? '' : num_suffix(n, bin)) :
|
80
|
+
('%.1f%% (%s/%s)' % adv_vals)
|
81
|
+
left =
|
82
|
+
if @_advance_time[:avg].nil?
|
83
|
+
''
|
84
|
+
else
|
85
|
+
left_time = @_advance_time[:avg] * (total - n) / 60 # <- in minutes
|
86
|
+
left_time < 0.01 ? ' ' :
|
87
|
+
left_time < 1 ? ('%.0fs left' % (left_time * 60)) :
|
88
|
+
left_time > 1440 ? ('%.1fd left' % (left_time / 1440)) :
|
89
|
+
left_time > 60 ? ('%.1fh left' % (left_time / 60)) :
|
90
|
+
('%.1fm left' % left_time)
|
91
|
+
end
|
92
|
+
$stderr.print("[%s] %s %s %s \r" % [Time.now, step, adv, left])
|
59
93
|
end
|
60
94
|
|
61
95
|
##
|
data/lib/miga/daemon/base.rb
CHANGED
data/lib/miga/json.rb
CHANGED
@@ -34,17 +34,29 @@ class MiGA::Json < MiGA::MiGA
|
|
34
34
|
# +opts+.
|
35
35
|
def parse(path, opts = {})
|
36
36
|
opts = default_opts(opts)
|
37
|
-
cont = opts[:contents] ? path : File.read(path)
|
38
|
-
raise "Empty descriptor: #{opts[:contents] ? "''" : path}." if cont.empty?
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
# Read JSON
|
39
|
+
cont = path
|
40
|
+
12.times do
|
41
|
+
cont = File.read(path)
|
42
|
+
break unless cont.empty?
|
43
|
+
sleep 1 # Wait up to 12 seconds for racing processes (iff empty file)
|
44
|
+
end unless opts[:contents]
|
45
|
+
raise "Empty descriptor: #{opts[:contents] ? "''" : path}" if cont.empty?
|
46
|
+
|
47
|
+
# Parse JSON
|
48
|
+
params = { symbolize_names: opts[:symbolize],
|
49
|
+
create_additions: opts[:additions] }
|
50
|
+
y = JSON.parse(cont, params)
|
51
|
+
|
52
|
+
# Add defaults
|
43
53
|
unless opts[:default].nil?
|
44
54
|
opts[:default] = parse(opts[:default]) if opts[:default].is_a? String
|
45
55
|
y.each { |k, v| opts[:default][k] = v }
|
46
56
|
y = opts[:default]
|
47
57
|
end
|
58
|
+
|
59
|
+
# Return
|
48
60
|
y
|
49
61
|
end
|
50
62
|
|
data/lib/miga/version.rb
CHANGED
@@ -8,7 +8,7 @@ module MiGA
|
|
8
8
|
# - Float representing the major.minor version.
|
9
9
|
# - Integer representing gem releases of the current version.
|
10
10
|
# - Integer representing minor changes that require new version number.
|
11
|
-
VERSION = [0.7, 16,
|
11
|
+
VERSION = [0.7, 16, 6]
|
12
12
|
|
13
13
|
##
|
14
14
|
# Nickname for the current major.minor version.
|
@@ -16,7 +16,7 @@ module MiGA
|
|
16
16
|
|
17
17
|
##
|
18
18
|
# Date of the current gem release.
|
19
|
-
VERSION_DATE = Date.new(2020,
|
19
|
+
VERSION_DATE = Date.new(2020, 11, 22)
|
20
20
|
|
21
21
|
##
|
22
22
|
# Reference of MiGA.
|
data/scripts/project_stats.bash
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miga-base
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.16.
|
4
|
+
version: 0.7.16.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luis M. Rodriguez-R
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: daemons
|