miga-base 0.7.16.12 → 0.7.18.0
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/lib/miga/cli/action/doctor/base.rb +11 -31
- data/lib/miga/daemon.rb +14 -7
- data/lib/miga/daemon/base.rb +7 -1
- data/lib/miga/dataset.rb +2 -3
- data/lib/miga/dataset/result.rb +4 -4
- data/lib/miga/sqlite.rb +49 -0
- data/lib/miga/version.rb +2 -2
- data/scripts/maintenance.bash +9 -0
- data/scripts/project_stats.bash +3 -0
- data/test/daemon_test.rb +21 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78b020bda6120b5a284100b9544d7a488d385630f21b5d6d5e2bb9b365c832fb
|
4
|
+
data.tar.gz: d8332711fdf86308726700654ee8db91bb097f022a26e1240e62d107efa833a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b766a40acf37193204e6369e07f2ecba1a67aa6141133654ab69f89b2ba9a63a959bd3f5b7fd21c56542eea7e3174cc342b05dc76b73ed27c6a2b273c546ca9
|
7
|
+
data.tar.gz: 6f8d791b9bf443a1eb43198625ebce48501ebaa3680be0c4cef55931b176fd2365407865e6e43cd549217ada6c67e5c86b156bd0816b80f91c388af812af810c
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'miga/cli/action'
|
2
|
-
require '
|
2
|
+
require 'miga/sqlite'
|
3
3
|
|
4
4
|
class MiGA::Cli::Action::Doctor < MiGA::Cli::Action
|
5
5
|
end
|
@@ -10,9 +10,7 @@ module MiGA::Cli::Action::Doctor::Base
|
|
10
10
|
# tables saving +metric+ (:ani or :aai) and call +blk+ if the
|
11
11
|
# file is corrupt or doesn't contain the expected structure
|
12
12
|
def check_sqlite3_database(db_file, metric, &blk)
|
13
|
-
|
14
|
-
conn.execute("select count(*) from #{metric}").first
|
15
|
-
end
|
13
|
+
MiGA::SQLite.new(db_file).run("select count(*) from #{metric}")
|
16
14
|
rescue SQLite3::SQLException, SQLite3::CorruptException
|
17
15
|
blk.call
|
18
16
|
end
|
@@ -107,11 +105,7 @@ module MiGA::Cli::Action::Doctor::Base
|
|
107
105
|
dist = dataset.result(:distances) or return
|
108
106
|
path = dist.file_path(:aai_db) or return
|
109
107
|
|
110
|
-
|
111
|
-
SQLite3::Database.new(path) do |conn|
|
112
|
-
o = conn.execute('select seq2 from aai').map(&:first)
|
113
|
-
end
|
114
|
-
o
|
108
|
+
MiGA::SQLite.new(path).run('select seq2 from aai').map(&:first)
|
115
109
|
end
|
116
110
|
|
117
111
|
##
|
@@ -120,34 +114,20 @@ module MiGA::Cli::Action::Doctor::Base
|
|
120
114
|
def save_bidirectional(a, b)
|
121
115
|
each_database_file(a) do |db_file, metric, result|
|
122
116
|
data = nil
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
"from #{metric} where seq2 = ? limit 1", b.name
|
128
|
-
).first
|
129
|
-
end
|
117
|
+
data = MiGA::SQLite.new(db_file).run(
|
118
|
+
"select seq1, seq2, #{metric}, sd, n, omega " +
|
119
|
+
"from #{metric} where seq2 = ? limit 1", b.name
|
120
|
+
).first
|
130
121
|
next if data.nil? || data.empty?
|
131
122
|
|
132
123
|
db_file_b = File.join(File.dirname(db_file), "#{b.name}.db")
|
133
124
|
next unless File.exist?(db_file_b)
|
134
125
|
|
135
126
|
data[0], data[1] = data[1], data[0]
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
150
|
-
end
|
127
|
+
MiGA::SQLite.new(db_file_b).run(
|
128
|
+
"insert into #{metric} (seq1, seq2, #{metric}, sd, n, omega) " +
|
129
|
+
"values(?, ?, ?, ?, ?, ?)", data
|
130
|
+
)
|
151
131
|
end
|
152
132
|
end
|
153
133
|
end
|
data/lib/miga/daemon.rb
CHANGED
@@ -73,7 +73,7 @@ class MiGA::Daemon < MiGA::MiGA
|
|
73
73
|
say 'MiGA:%s launched' % project.name
|
74
74
|
say '-----------------------------------'
|
75
75
|
miga_say "Saving log to: #{output_file}" unless show_log?
|
76
|
-
|
76
|
+
queue_maintenance
|
77
77
|
load_status
|
78
78
|
say 'Configuration options:'
|
79
79
|
say @runopts.to_s
|
@@ -92,7 +92,7 @@ class MiGA::Daemon < MiGA::MiGA
|
|
92
92
|
flush!
|
93
93
|
if (loop_i % 12).zero?
|
94
94
|
purge!
|
95
|
-
|
95
|
+
queue_maintenance
|
96
96
|
end
|
97
97
|
save_status
|
98
98
|
sleep(latency)
|
@@ -100,11 +100,13 @@ class MiGA::Daemon < MiGA::MiGA
|
|
100
100
|
true
|
101
101
|
end
|
102
102
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
103
|
+
##
|
104
|
+
# Queue maintenance tasks as an analysis job
|
105
|
+
def queue_maintenance
|
106
|
+
return if bypass_maintenance?
|
107
|
+
|
108
|
+
say 'Queueing maintenance tasks'
|
109
|
+
queue_job(:maintenance)
|
108
110
|
end
|
109
111
|
|
110
112
|
##
|
@@ -272,6 +274,11 @@ class MiGA::Daemon < MiGA::MiGA
|
|
272
274
|
# Avoid single datasets hogging resources
|
273
275
|
@jobs_to_run.rotate! rand(jobs_to_run.size)
|
274
276
|
|
277
|
+
# Prioritize project-wide jobs
|
278
|
+
project_jobs = @jobs_to_run.select { |i| i[:ds].nil? }
|
279
|
+
@jobs_to_run.delete_if { |i| i[:ds].nil? }
|
280
|
+
@jobs_to_run.prepend(*project_jobs)
|
281
|
+
|
275
282
|
# Launch as many +jobs_to_run+ as possible
|
276
283
|
while (hostk = next_host)
|
277
284
|
break if jobs_to_run.empty?
|
data/lib/miga/daemon/base.rb
CHANGED
@@ -17,7 +17,7 @@ module MiGA::Daemon::Base
|
|
17
17
|
if !force && v == 0 && k != :verbosity
|
18
18
|
raise "Daemon's #{k} cannot be set to zero"
|
19
19
|
end
|
20
|
-
when :shutdown_when_done, :show_log
|
20
|
+
when :shutdown_when_done, :show_log, :bypass_maintenance
|
21
21
|
v = !!v
|
22
22
|
when :nodelist
|
23
23
|
if v =~ /^\$/
|
@@ -63,6 +63,12 @@ module MiGA::Daemon::Base
|
|
63
63
|
!!runopts(:shutdown_when_done)
|
64
64
|
end
|
65
65
|
|
66
|
+
##
|
67
|
+
# Should the daemon ignore regular maintenance steps?
|
68
|
+
def bypass_maintenance?
|
69
|
+
!!runopts(:bypass_maintenance)
|
70
|
+
end
|
71
|
+
|
66
72
|
##
|
67
73
|
# Returns the level of verbosity for the daemon as an Integer, or 1 if unset.
|
68
74
|
# Verbosity levels are:
|
data/lib/miga/dataset.rb
CHANGED
@@ -7,7 +7,7 @@ require 'miga/metadata'
|
|
7
7
|
require 'miga/dataset/result'
|
8
8
|
require 'miga/dataset/status'
|
9
9
|
require 'miga/dataset/hooks'
|
10
|
-
require '
|
10
|
+
require 'miga/sqlite'
|
11
11
|
|
12
12
|
##
|
13
13
|
# Dataset representation in MiGA
|
@@ -190,8 +190,7 @@ class MiGA::Dataset < MiGA::MiGA
|
|
190
190
|
r = result(ref_project ? :taxonomy : :distances)
|
191
191
|
return nil if r.nil?
|
192
192
|
|
193
|
-
|
194
|
-
db.execute(
|
193
|
+
MiGA::SQLite.new(r.file_path(:aai_db)).run(
|
195
194
|
'SELECT seq2, aai FROM aai WHERE seq2 != ? ' \
|
196
195
|
'GROUP BY seq2 ORDER BY aai DESC LIMIT ?', [name, how_many]
|
197
196
|
)
|
data/lib/miga/dataset/result.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'miga/sqlite'
|
2
2
|
require 'miga/result'
|
3
3
|
require 'miga/dataset/base'
|
4
4
|
require 'miga/common/with_result'
|
@@ -151,13 +151,13 @@ module MiGA::Dataset::Result
|
|
151
151
|
db = r.file_path(db_type)
|
152
152
|
next if db.nil? || !File.size?(db)
|
153
153
|
|
154
|
-
sqlite_db =
|
154
|
+
sqlite_db = MiGA::SQLite.new(db)
|
155
155
|
table = db_type[-6..-4]
|
156
|
-
val = sqlite_db.
|
156
|
+
val = sqlite_db.run("select seq2 from #{table}")
|
157
157
|
next if val.empty?
|
158
158
|
|
159
159
|
(val.map(&:first) - ref).each do |extra|
|
160
|
-
sqlite_db.
|
160
|
+
sqlite_db.run("delete from #{table} where seq2=?", extra)
|
161
161
|
end
|
162
162
|
end
|
163
163
|
end
|
data/lib/miga/sqlite.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# @package MiGA
|
2
|
+
# @license Artistic-2.0
|
3
|
+
|
4
|
+
require 'sqlite3'
|
5
|
+
|
6
|
+
##
|
7
|
+
# SQLite3 wrapper for MiGA.
|
8
|
+
class MiGA::SQLite < MiGA::MiGA
|
9
|
+
class << self
|
10
|
+
##
|
11
|
+
# Default parsing options. Supported +opts+ keys:
|
12
|
+
# - +:busy_attempts+: Number of times to retry when database is busy
|
13
|
+
# (default: 3)
|
14
|
+
def default_opts(opts = {})
|
15
|
+
opts[:busy_attempts] ||= 3
|
16
|
+
opts
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Options hash
|
22
|
+
attr :opts
|
23
|
+
|
24
|
+
##
|
25
|
+
# Database absolute path
|
26
|
+
attr :path
|
27
|
+
|
28
|
+
##
|
29
|
+
# Create MiGA::SQLite with database in +path+ (without opening a connection)
|
30
|
+
# and options +opts+ (see +.default_opts+)
|
31
|
+
def initialize(path, opts = {})
|
32
|
+
@opts = MiGA::SQLite.default_opts(opts)
|
33
|
+
@path = File.absolute_path(path)
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Executes +cmd+ and returns the result
|
38
|
+
def run(*cmd)
|
39
|
+
busy_attempts ||= 0
|
40
|
+
conn = SQLite3::Database.new(path)
|
41
|
+
conn.execute(*cmd)
|
42
|
+
rescue SQLite3::BusyException => e
|
43
|
+
busy_attempts += 1
|
44
|
+
raise "Database busy #{path}: #{e.message}" if busy_attempts >= 3
|
45
|
+
|
46
|
+
sleep(1)
|
47
|
+
retry
|
48
|
+
end
|
49
|
+
end
|
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,
|
11
|
+
VERSION = [0.7, 18, 0]
|
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, 12,
|
19
|
+
VERSION_DATE = Date.new(2020, 12, 27)
|
20
20
|
|
21
21
|
##
|
22
22
|
# Reference of MiGA.
|
data/scripts/project_stats.bash
CHANGED
@@ -12,12 +12,15 @@ cd "$DIR"
|
|
12
12
|
miga date > "miga-project.start"
|
13
13
|
|
14
14
|
# Execute doctor
|
15
|
+
echo "# Doctor"
|
15
16
|
miga doctor -P "$PROJECT" -t "$CORES" -v
|
16
17
|
|
17
18
|
# Index taxonomy
|
19
|
+
echo "# Index taxonomy"
|
18
20
|
miga tax_index -P "$PROJECT" -i "miga-project.taxonomy.json" --ref --active
|
19
21
|
|
20
22
|
# Index metadata
|
23
|
+
echo "# Index metadata"
|
21
24
|
ruby -I "$MIGA/lib" \
|
22
25
|
"$MIGA/utils/index_metadata.rb" "$PROJECT" "miga-project.metadata.db"
|
23
26
|
|
data/test/daemon_test.rb
CHANGED
@@ -93,7 +93,7 @@ class DaemonTest < Test::Unit::TestCase
|
|
93
93
|
0 => /-{20}\n/,
|
94
94
|
1 => /MiGA:#{p.name} launched/,
|
95
95
|
2 => /-{20}\n/,
|
96
|
-
|
96
|
+
8 => /Probing running jobs\n/
|
97
97
|
}.each { |k, v| assert_match(v, l[k], "unexpected line: #{k}") }
|
98
98
|
ensure
|
99
99
|
begin
|
@@ -160,8 +160,9 @@ class DaemonTest < Test::Unit::TestCase
|
|
160
160
|
assert_equal(0, d1.jobs_running.size)
|
161
161
|
assert_equal(0, d1.jobs_to_run.size)
|
162
162
|
capture_stderr { d1.in_loop }
|
163
|
+
# 3 dataset jobs + 1 maintenance job:
|
163
164
|
assert_equal(1, d1.jobs_running.size)
|
164
|
-
assert_equal(
|
165
|
+
assert_equal(3, d1.jobs_to_run.size)
|
165
166
|
end
|
166
167
|
|
167
168
|
def test_maxjobs_runopts
|
@@ -172,7 +173,7 @@ class DaemonTest < Test::Unit::TestCase
|
|
172
173
|
assert_equal(0, d1.jobs_to_run.size)
|
173
174
|
capture_stderr { d1.in_loop }
|
174
175
|
assert_equal(2, d1.jobs_running.size)
|
175
|
-
assert_equal(
|
176
|
+
assert_equal(2, d1.jobs_to_run.size)
|
176
177
|
end
|
177
178
|
|
178
179
|
def test_load_status
|
@@ -232,6 +233,7 @@ class DaemonTest < Test::Unit::TestCase
|
|
232
233
|
end
|
233
234
|
|
234
235
|
def test_shutdown_when_done
|
236
|
+
daemon.runopts(:bypass_maintenance, true)
|
235
237
|
daemon.runopts(:shutdown_when_done, true)
|
236
238
|
out = capture_stderr { assert { !daemon.in_loop } }.string
|
237
239
|
assert_match(/Nothing else to do/, out)
|
@@ -317,4 +319,20 @@ class DaemonTest < Test::Unit::TestCase
|
|
317
319
|
out = capture_stderr { d1.in_loop }.string
|
318
320
|
assert_match(/Daemon loop start/, out)
|
319
321
|
end
|
322
|
+
|
323
|
+
def test_bypass_maintenance
|
324
|
+
# Default (run maintenance)
|
325
|
+
d = daemon(0)
|
326
|
+
d.runopts(:latency, 0, true)
|
327
|
+
capture_stderr { d.in_loop }
|
328
|
+
assert_equal(1, d.jobs_running.size)
|
329
|
+
assert_equal(:maintenance, d.jobs_running.first[:job])
|
330
|
+
|
331
|
+
# Bypassing maintenance
|
332
|
+
d = daemon(1)
|
333
|
+
d.runopts(:latency, 0, true)
|
334
|
+
d.runopts(:bypass_maintenance, true)
|
335
|
+
capture_stderr { d.in_loop }
|
336
|
+
assert_equal([], d.jobs_running)
|
337
|
+
end
|
320
338
|
end
|
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.
|
4
|
+
version: 0.7.18.0
|
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-12-
|
11
|
+
date: 2020-12-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: daemons
|
@@ -196,6 +196,7 @@ files:
|
|
196
196
|
- lib/miga/result/dates.rb
|
197
197
|
- lib/miga/result/source.rb
|
198
198
|
- lib/miga/result/stats.rb
|
199
|
+
- lib/miga/sqlite.rb
|
199
200
|
- lib/miga/tax_dist.rb
|
200
201
|
- lib/miga/tax_index.rb
|
201
202
|
- lib/miga/taxonomy.rb
|
@@ -211,6 +212,7 @@ files:
|
|
211
212
|
- scripts/essential_genes.bash
|
212
213
|
- scripts/haai_distances.bash
|
213
214
|
- scripts/init.bash
|
215
|
+
- scripts/maintenance.bash
|
214
216
|
- scripts/miga.bash
|
215
217
|
- scripts/mytaxa.bash
|
216
218
|
- scripts/mytaxa_scan.bash
|