miga-base 0.7.16.0 → 0.7.16.6
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.
- 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
|