miga-base 0.7.16.1 → 0.7.16.3

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: c515f327c9d7178b1891283f849d422885b3640f8cded39cfccd048e354acf16
4
- data.tar.gz: 889a399e0fa68b54c901ec513e2049ab046593bc433185511516dbf9b3cedb7d
3
+ metadata.gz: 51173aea1659d14d35f485b22b4371bdf8cf9d16ae81c673d09c25cf3e36d1ac
4
+ data.tar.gz: 4c6cbaed4bc9f0ea2f71d75ccfd22e3b0ac38e62c138166b768feb91c9a804b3
5
5
  SHA512:
6
- metadata.gz: f4a9d5515ddf4b208b81612ceafcdae0eeb9cd37266df5f0175cef859adb9b24fd6e9ac5adf384ad9c91f8ecc08d6d5522eef8b9dd96e7d39740b14f83fdaf53
7
- data.tar.gz: 117bc5b917e1008084e064cd4d87f290a83b6962e93560abfad254d23345a7685bf9ad3a345f2ade98ea5c13b4be52ccf608683ede8c320f3b8ee1250c2cec32
6
+ metadata.gz: 6e00443678373cb3125e1d73d111ff909cfaa092c92ffd00089e2d122bad0f298133e4c4b2da00370d4ff56e3d1281b8e3ebe316e23fa675b73b217b6045e4e8
7
+ data.tar.gz: f5d5f2981f86e0a79a1c96b81cdb76853eeacd11a14c23d630bcf067d390074d40273159b2b95c3ea33d88d1ca1c66bce19338809af410e48a0db2138d4974d3
@@ -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
- n, k = cli.load_project.dataset_names.size, 0
63
- cli.load_project.each_dataset do |d|
64
- cli.advance('Datasets:', k += 1, n, false)
65
- d.recalculate_status
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
- n, k = cli.load_project.dataset_names.size, 0
75
- cli.load_project.each_dataset do |d|
76
- cli.advance('Datasets:', k += 1, n, false)
77
- each_database_file(d) do |db_file, metric, result|
78
- check_sqlite3_database(db_file, metric) do
79
- cli.say(" > Removing malformed database from #{d.name}:#{result} ")
80
- File.unlink(db_file)
81
- r = d.result(result) or next
82
- [r.path(:done), r.path].each { |f| File.unlink(f) if File.exist?(f) }
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 that reference distances are bidirectional'
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, k = ref_ds.size, 0
96
- ref_ds.each do |d|
97
- cli.advance('Datasets:', k += 1, n, false)
98
- saved = saved_targets(d)
99
- next if saved.nil?
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
- to_save = ref_names - saved
102
- to_save.each { |k| save_bidirectional(cli.load_project.dataset(k), d) }
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
- conn.execute(
138
- "insert into #{metric} (seq1, seq2, #{metric}, sd, n, omega) " +
139
- "values(?, ?, ?, ?, ?, ?)", data
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
@@ -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]
@@ -52,10 +52,39 @@ 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
- adv = total.nil? ? (n == 0 ? '' : num_suffix(n, bin)) :
56
- ('%.1f%% (%s/%s)' % [100.0 * n / total,
57
- num_suffix(n, bin), num_suffix(total, bin)])
58
- $stderr.print("[%s] %s %s \r" % [Time.now, step, adv])
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
+ unless total.nil? || @_advance_time[:last].nil? || @_advance_time[:n] == n
65
+ this_time = Time.now - @_advance_time[:last]
66
+ @_advance_time[:avg] ||= this_time / (n - @_advance_time[:n])
67
+ @_advance_time[:avg] = 0.99 * @_advance_time[:avg] + 0.01 * this_time
68
+ end
69
+ @_advance_time[:last] = Time.now
70
+ @_advance_time[:n] = n
71
+
72
+ # Report
73
+ adv_vals = [100.0 * n / total, num_suffix(n, bin), num_suffix(total, bin)]
74
+ adv =
75
+ total.nil? ? (n == 0 ? '' : num_suffix(n, bin)) :
76
+ ('%.1f%% (%s/%s)' % adv_vals)
77
+ left =
78
+ if @_advance_time[:avg].nil?
79
+ ''
80
+ else
81
+ left_time = @_advance_time[:avg] * (total - n) / 60
82
+ left_time < 0.01 ? ' ' :
83
+ left_time < 1 ? ('%.0fs left' % (left_time * 60)) :
84
+ left_time > 60 ? ('%.1fh left' % (left_time / 60)) :
85
+ ('%.1fm left' % left_time)
86
+ end
87
+ $stderr.print("[%s] %s %s %s \r" % [Time.now, step, adv, left])
59
88
  end
60
89
 
61
90
  ##
@@ -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, 1]
11
+ VERSION = [0.7, 16, 3]
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, 10, 19)
19
+ VERSION_DATE = Date.new(2020, 10, 27)
20
20
 
21
21
  ##
22
22
  # Reference of MiGA.
@@ -12,7 +12,7 @@ cd "$DIR"
12
12
  miga date > "miga-project.start"
13
13
 
14
14
  # Execute doctor
15
- miga doctor -P "$PROJECT" -v
15
+ miga doctor -P "$PROJECT" -t "$CORES" -v
16
16
 
17
17
  # Index taxonomy
18
18
  miga tax_index -P "$PROJECT" -i "miga-project.taxonomy.json" --ref --active
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.1
4
+ version: 0.7.16.3
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-10-19 00:00:00.000000000 Z
11
+ date: 2020-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: daemons