miga-base 0.7.16.10 → 0.7.19.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80bc5ff58583017ef3cb4962c7a2ac4086e602fc9bd2319a35cf7edd36c211d3
4
- data.tar.gz: 6ae15844eff00f4adcf794f7b56f940cc4af96a555785a1397dfd3781e62af80
3
+ metadata.gz: bc5df224531c2f5e902304b478aabe0ba18c02b836c5bab66a675257a3739a08
4
+ data.tar.gz: 438b9f2cefad3ecc3b65e17f81d5708f6a589c8b34f22b63235cf4123a156922
5
5
  SHA512:
6
- metadata.gz: bfb11a9ffe5a5b8d64578512cf5ed29a6272f90760015092a35d2e17a008cd84bdf0c2c30f6988941815b196e4c492abf7b5929166b2ef6357297e3784a91936
7
- data.tar.gz: 77846f20c76d8ba84b3c1351395da6cc410e8947bb82491d9e93c7f1a1931c22ec975eb5ffc94117524cddf83c30890ea84bbabe7585783aa2034274093c7e88
6
+ metadata.gz: 506dd5c19259071abd5cf0a130a70557967833edc520fada73030372d7736f2fe114ce4879bc224e37bcbe407a566bbd3cef39a5bc8ec9669c9c4cd1e63edb74
7
+ data.tar.gz: 4edb685f9a4adb69339e5ef477d4a0a332da606b402d380e3eab77a055ab94582be3be90f904e9403bc20d3f81c3753ed85df8a43bd9afc3e97b41f88cfd9fb1
@@ -1,5 +1,5 @@
1
1
  require 'miga/cli/action'
2
- require 'sqlite3'
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
- SQLite3::Database.new(db_file) do |conn|
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
- o = []
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
- SQLite3::Database.new(db_file) do |conn|
124
- data =
125
- conn.execute(
126
- "select seq1, seq2, #{metric}, sd, n, omega " +
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
- SQLite3::Database.new(db_file_b) do |conn|
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
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
@@ -25,6 +25,10 @@ class MiGA::Cli::Action::Lair < MiGA::Cli::Action
25
25
  '-p', '--path PATH',
26
26
  '(Mandatory) Path to the directory where the MiGA projects are located'
27
27
  ) { |v| cli[:path] = v }
28
+ opt.on(
29
+ '--exclude NAME1,NAME2,NAME3', Array,
30
+ 'Exclude these projects (identified by name) from the lair'
31
+ ) { |v| cli[:exclude] = v }
28
32
  opt.on(
29
33
  '--json PATH',
30
34
  'Path to a custom daemon definition in json format'
@@ -80,19 +84,22 @@ class MiGA::Cli::Action::Lair < MiGA::Cli::Action
80
84
 
81
85
  def perform
82
86
  cli.ensure_par(path: '-p')
87
+ k_opts = %i[
88
+ json latency wait_for keep_inactive trust_timestamp name dry exclude
89
+ ]
90
+ opts = Hash[k_opts.map { |k| [k, cli[k]] }]
91
+ lair = MiGA::Lair.new(cli[:path], opts)
92
+
83
93
  case cli.operation.to_sym
84
94
  when :terminate
85
- MiGA::Lair.new(cli[:path]).terminate_daemons
95
+ lair.terminate_daemons
86
96
  when :list
87
97
  o = []
88
- MiGA::Lair.new(cli[:path]).each_daemon do |d|
98
+ lair.each_daemon do |d|
89
99
  o << [d.daemon_name, d.class, d.daemon_home, d.active?, d.last_alive]
90
100
  end
91
101
  cli.table(%w[name class path active last_alive], o)
92
102
  else
93
- k_opts = %i[json latency wait_for keep_inactive trust_timestamp name dry]
94
- opts = Hash[k_opts.map { |k| [k, cli[k]] }]
95
- lair = MiGA::Lair.new(cli[:path], opts)
96
103
  lair.daemon(cli.operation, cli[:daemon_opts])
97
104
  end
98
105
  end
@@ -59,7 +59,7 @@ class MiGA::Cli::Action::Run < MiGA::Cli::Action
59
59
  "MIGA=#{miga.shellescape}", "CORES=#{cli[:thr]}"]
60
60
  obj = cli.load_project_or_dataset
61
61
  klass = obj.class
62
- virtual_task = [:p, :d].include?(cli[:result])
62
+ virtual_task = %i[p d maintenance].include?(cli[:result])
63
63
  cmd << "DATASET=#{obj.name.shellescape}" if obj.is_a? MiGA::Dataset
64
64
  if klass.RESULT_DIRS[cli[:result]].nil? and not virtual_task
65
65
  raise "Unsupported #{klass.to_s.sub(/.*::/, '')} result: #{cli[:result]}."
@@ -184,7 +184,7 @@ module MiGA::Cli::Action::Wf
184
184
  def call_cli(cmd)
185
185
  cmd << '-v' if cli[:verbose]
186
186
  MiGA::MiGA.DEBUG "Cli::Action::Wf.call_cli #{cmd}"
187
- MiGA::Cli.new(cmd.map(&:to_s)).launch
187
+ MiGA::Cli.new(cmd.map(&:to_s)).launch(true)
188
188
  end
189
189
 
190
190
  def run_daemon
@@ -74,10 +74,13 @@ class MiGA::MiGA
74
74
  @_advance_time[:n] = n
75
75
 
76
76
  # Report
77
- adv_vals = [100.0 * n / total, num_suffix(n, bin), num_suffix(total, bin)]
78
77
  adv =
79
- total.nil? ? (n == 0 ? '' : num_suffix(n, bin)) :
80
- ('%.1f%% (%s/%s)' % adv_vals)
78
+ if total.nil?
79
+ (n == 0 ? '' : num_suffix(n, bin))
80
+ else
81
+ vals = [100.0 * n / total, num_suffix(n, bin), num_suffix(total, bin)]
82
+ ('%.1f%% (%s/%s)' % vals)
83
+ end
81
84
  left =
82
85
  if @_advance_time[:avg].nil?
83
86
  ''
@@ -158,7 +158,7 @@ module MiGA::Common::WithDaemon
158
158
  # Returns the status of the daemon with +opts+
159
159
  def status(opts = [], wait = true)
160
160
  if active?
161
- say "Running with pid #{File.read(pid_file)}"
161
+ say "Running with pid #{File.size?(pid_file) ? File.read(pid_file) : '?'}"
162
162
  else
163
163
  say 'Not running'
164
164
  end
@@ -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
- recalculate_status!
76
+ queue_maintenance
77
77
  load_status
78
78
  say 'Configuration options:'
79
79
  say @runopts.to_s
@@ -92,8 +92,7 @@ class MiGA::Daemon < MiGA::MiGA
92
92
  flush!
93
93
  if (loop_i % 12).zero?
94
94
  purge!
95
- # TEMPORARILY DISABLED:
96
- # recalculate_status!
95
+ queue_maintenance
97
96
  end
98
97
  save_status
99
98
  sleep(latency)
@@ -101,9 +100,13 @@ class MiGA::Daemon < MiGA::MiGA
101
100
  true
102
101
  end
103
102
 
104
- def recalculate_status!
105
- say 'Recalculating status for all datasets'
106
- project.each_dataset(&:recalculate_status)
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)
107
110
  end
108
111
 
109
112
  ##
@@ -179,6 +182,7 @@ class MiGA::Daemon < MiGA::MiGA
179
182
  unless show_log?
180
183
  n = project.dataset_names.count
181
184
  k = jobs_to_run.size + jobs_running.size
185
+ k -= 1 unless get_job(:maintenance).nil?
182
186
  advance('Datasets:', n - k, n, false)
183
187
  miga_say if k == 0
184
188
  end
@@ -271,6 +275,11 @@ class MiGA::Daemon < MiGA::MiGA
271
275
  # Avoid single datasets hogging resources
272
276
  @jobs_to_run.rotate! rand(jobs_to_run.size)
273
277
 
278
+ # Prioritize: Project-wide > MiGA Online queries > Other datasets
279
+ @jobs_to_run.sort_by! do |job|
280
+ job[:ds].nil? ? 1 : job[:ds_name] =~ /^qG_/ ? 2 : 3
281
+ end
282
+
274
283
  # Launch as many +jobs_to_run+ as possible
275
284
  while (hostk = next_host)
276
285
  break if jobs_to_run.empty?
@@ -309,11 +318,13 @@ class MiGA::Daemon < MiGA::MiGA
309
318
  job[:hostk] = hostk
310
319
  job[:cmd] = job[:cmd].miga_variables(host: nodelist[hostk])
311
320
  job[:pid] = spawn job[:cmd]
312
- Process.detach job[:pid] unless [nil, '', 0].include?(job[:pid])
321
+ MiGA::MiGA.DEBUG "Detaching PID: #{job[:pid]}"
322
+ Process.detach(job[:pid]) unless [nil, '', 0].include?(job[:pid])
313
323
  when 'bash'
314
324
  # Local job
315
325
  job[:pid] = spawn job[:cmd]
316
- Process.detach job[:pid] unless [nil, '', 0].include?(job[:pid])
326
+ MiGA::MiGA.DEBUG "Detaching PID: #{job[:pid]}"
327
+ Process.detach(job[:pid]) unless [nil, '', 0].include?(job[:pid])
317
328
  else
318
329
  # Schedule cluster job (qsub, msub, slurm)
319
330
  job[:pid] = `#{job[:cmd]}`.chomp
@@ -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:
@@ -7,7 +7,11 @@ require 'miga/metadata'
7
7
  require 'miga/dataset/result'
8
8
  require 'miga/dataset/status'
9
9
  require 'miga/dataset/hooks'
10
- require 'sqlite3'
10
+
11
+ # This library is only required by +#closest_relatives+, so it is now
12
+ # being loaded on call instead to allow most of miga-base to work without
13
+ # issue in systems with problematic SQLite3 installations.
14
+ # require 'miga/sqlite'
11
15
 
12
16
  ##
13
17
  # Dataset representation in MiGA
@@ -190,8 +194,8 @@ class MiGA::Dataset < MiGA::MiGA
190
194
  r = result(ref_project ? :taxonomy : :distances)
191
195
  return nil if r.nil?
192
196
 
193
- db = SQLite3::Database.new(r.file_path(:aai_db))
194
- db.execute(
197
+ require 'miga/sqlite'
198
+ MiGA::SQLite.new(r.file_path(:aai_db)).run(
195
199
  'SELECT seq2, aai FROM aai WHERE seq2 != ? ' \
196
200
  'GROUP BY seq2 ORDER BY aai DESC LIMIT ?', [name, how_many]
197
201
  )
@@ -1,8 +1,12 @@
1
- require 'sqlite3'
2
1
  require 'miga/result'
3
2
  require 'miga/dataset/base'
4
3
  require 'miga/common/with_result'
5
4
 
5
+ # This library is only required by +#cleanup_distances!+, so it is now
6
+ # being loaded on call instead to allow most of miga-base to work without
7
+ # issue in systems with problematic SQLite3 installations.
8
+ # require 'miga/sqlite'
9
+
6
10
  ##
7
11
  # Helper module including specific functions to add dataset results
8
12
  module MiGA::Dataset::Result
@@ -144,20 +148,21 @@ module MiGA::Dataset::Result
144
148
  # the project as reference datasets.
145
149
  def cleanup_distances!
146
150
  r = get_result(:distances)
147
- ref = project.datasets.select(&:ref?).select(&:active?).map(&:name)
148
151
  return if r.nil?
149
152
 
153
+ require 'miga/sqlite'
154
+ ref = project.datasets.select(&:ref?).select(&:active?).map(&:name)
150
155
  %i[haai_db aai_db ani_db].each do |db_type|
151
156
  db = r.file_path(db_type)
152
157
  next if db.nil? || !File.size?(db)
153
158
 
154
- sqlite_db = SQLite3::Database.new db
159
+ sqlite_db = MiGA::SQLite.new(db)
155
160
  table = db_type[-6..-4]
156
- val = sqlite_db.execute "select seq2 from #{table}"
161
+ val = sqlite_db.run("select seq2 from #{table}")
157
162
  next if val.empty?
158
163
 
159
164
  (val.map(&:first) - ref).each do |extra|
160
- sqlite_db.execute "delete from #{table} where seq2=?", extra
165
+ sqlite_db.run("delete from #{table} where seq2=?", extra)
161
166
  end
162
167
  end
163
168
  end
@@ -31,6 +31,7 @@ class MiGA::Lair < MiGA::MiGA
31
31
  # by default: true
32
32
  # - dry: Only report when daemons would be launched, but don't actually launch
33
33
  # them
34
+ # - exclude: Array of project names to be excluded from the lair
34
35
  def initialize(path, opts = {})
35
36
  @path = File.expand_path(path)
36
37
  @options = opts
@@ -41,7 +42,8 @@ class MiGA::Lair < MiGA::MiGA
41
42
  keep_inactive: false,
42
43
  trust_timestamp: true,
43
44
  name: File.basename(@path),
44
- dry: false
45
+ dry: false,
46
+ exclude: []
45
47
  }.each { |k, v| @options[k] = v if @options[k].nil? }
46
48
  end
47
49
 
@@ -109,7 +111,7 @@ class MiGA::Lair < MiGA::MiGA
109
111
  project = MiGA::Project.load(f)
110
112
  raise "Cannot load project: #{f}" if project.nil?
111
113
 
112
- yield(project)
114
+ yield(project) unless options[:exclude].include?(project.name)
113
115
  elsif Dir.exist? f
114
116
  each_project(f) { |p| yield(p) }
115
117
  end
@@ -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
@@ -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, 10]
11
+ VERSION = [0.7, 19, 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, 9)
19
+ VERSION_DATE = Date.new(2021, 1, 2)
20
20
 
21
21
  ##
22
22
  # Reference of MiGA.
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+ # Available variables: $PROJECT, $RUNTYPE, $MIGA, $CORES
3
+ set -e
4
+ SCRIPT="maintenance"
5
+ # shellcheck source=scripts/miga.bash
6
+ . "$MIGA/scripts/miga.bash" || exit 1
7
+
8
+ miga doctor --only status -P "$PROJECT" -t "$CORES" -v
9
+
@@ -11,17 +11,17 @@ function exists { [[ -e "$1" ]] ; }
11
11
  function fx_exists { [[ $(type -t "$1") == "function" ]] ; }
12
12
 
13
13
  if [[ "$SCRIPT" != "d" && "$SCRIPT" != "p" ]] ; then
14
- echo '############'
15
- echo -n "Date: " ; miga date
16
- echo "Hostname: $(hostname)"
17
- echo "MiGA: $MIGA"
18
- echo "Task: $SCRIPT"
19
- echo "Project: $PROJECT"
14
+ echo ""
15
+ echo "######[ $SCRIPT ]######"
16
+ echo "# Date: $(miga date)"
17
+ echo "# Host: $(hostname)"
18
+ echo "# MiGA: $MIGA"
19
+ echo "# Project: $PROJECT"
20
20
  if [[ -n $DATASET ]] ; then
21
- echo "Dataset: $DATASET"
21
+ echo "# Dataset: $DATASET"
22
22
  miga edit -P "$PROJECT" -D "$DATASET" -m "_step=$SCRIPT"
23
23
  fi
24
- echo '------------'
24
+ echo '#------------'
25
25
  fi
26
26
 
27
27
  true
@@ -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
 
@@ -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
- 6 => /Probing running jobs\n/
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(2, d1.jobs_to_run.size)
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(1, d1.jobs_to_run.size)
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
@@ -5,21 +5,17 @@ require 'miga'
5
5
 
6
6
  ARGV[1] or abort "Usage: #{$0} path/to/project threads"
7
7
 
8
- $stderr.puts 'Cleaning databases...'
9
8
  p = MiGA::Project.load(ARGV[0])
10
- ds_names = p.dataset_names
9
+ dsn = p.dataset_names
11
10
  thr = ARGV[1].to_i
12
11
 
13
- pc = [0] + (1..100).map { |i| ds_names.size * i / 100 }
14
- $stderr.puts (('.' * 9 + '|') * 10) + ' 100%'
12
+ m = MiGA::MiGA.new
13
+ m.say 'Cleaning Databases'
15
14
 
16
15
  (0..thr - 1).each do |t|
17
16
  fork do
18
- ds_names.each_with_index do |i, idx|
19
- while t == 0 and idx + 1 > pc.first
20
- $stderr.print '#'
21
- pc.shift
22
- end
17
+ dsn.each_with_index do |i, idx|
18
+ m.advance('Dataset:', dsn.size, idx + 1) if t == 0
23
19
  next unless (idx % thr) == t
24
20
 
25
21
  d = p.dataset(i)
@@ -30,4 +26,6 @@ $stderr.puts (('.' * 9 + '|') * 10) + ' 100%'
30
26
  end
31
27
  end
32
28
  Process.waitall
33
- $stderr.puts ' Done'
29
+ m.advance('Dataset:', dsn.size, dsn.size)
30
+ m.say
31
+
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.10
4
+ version: 0.7.19.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-09 00:00:00.000000000 Z
11
+ date: 2021-01-02 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