fbe 0.49.0 → 0.49.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75b5c811806afc0a6b0d5982d06a1624b6904b93ae151aa90c7cfa24d84945a0
4
- data.tar.gz: 35c528503b021c5729b2400eb2c907e81fa8a5064e6ec5d14f930060e4fac685
3
+ metadata.gz: 8b2279330d7d5bfd9b1f0cd264e1922af79eb601fe2cb7d006cb9f0ace259b90
4
+ data.tar.gz: 6dcbf736f483cf44bb7ee4b5c0a265559e7a64f911eac7f50b598b01eb457940
5
5
  SHA512:
6
- metadata.gz: 4117821cd66f1a138430e80ae34598440eee4de363db299997faa39fc77355dd382d73e70f9ba8f00111ccda29087e45f80e3cab1b267b270657280c7ce74864
7
- data.tar.gz: 39eaa129a3ac957b5d6d675f8d8412c8c63f2a915b518b13195b3f36e3ac1f18dc47e538d2a9cce9f4c3f7381ea4c19448eec66a7b3c67e255cf481bc1b07321
6
+ metadata.gz: b2df90fc91e4d5a1ebff260a70378b40c82fa1d8c4f4e8b52a31c2fd0f6e1a11b3f8696cc3a01f3c6d20faf9d04a34445ddc9a93db41b7cda3a1f15170d8258f
7
+ data.tar.gz: b01156ba17d9330d2341b46b6386ae344f3f9661560756356b1a9c1a82b0206b9d4ca03c3bc05aa5d20a438464b666efba54287248b8fd780e2ca44194a55446
@@ -10,10 +10,12 @@ name: actionlint
10
10
  pull_request:
11
11
  branches:
12
12
  - master
13
+ permissions:
14
+ contents: read
13
15
  jobs:
14
16
  actionlint:
15
17
  timeout-minutes: 15
16
18
  runs-on: ubuntu-24.04
17
19
  steps:
18
- - uses: actions/checkout@v6
19
- - uses: reviewdog/action-actionlint@v1.72.0
20
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
21
+ - uses: reviewdog/action-actionlint@be0761e4c1bab7cfdfca56cd03d4bb6253e39a4a
@@ -7,19 +7,21 @@ name: codecov
7
7
  push:
8
8
  branches:
9
9
  - master
10
+ permissions:
11
+ contents: read
10
12
  jobs:
11
13
  codecov:
12
14
  timeout-minutes: 15
13
15
  runs-on: ubuntu-24.04
14
16
  steps:
15
- - uses: actions/checkout@v6
16
- - uses: ruby/setup-ruby@v1
17
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
18
+ - uses: ruby/setup-ruby@d45b1a4e94b71acab930e56e79c6aa188764e7f9
17
19
  with:
18
20
  ruby-version: .ruby-version
19
21
  bundler-cache: true
20
22
  - run: bundle config set --global path "$(pwd)/vendor/bundle"
21
23
  - run: bundle install --no-color
22
24
  - run: bundle exec rake
23
- - uses: codecov/codecov-action@v7
25
+ - uses: codecov/codecov-action@a99c28d3f0da835de33ff2feb2e15691c7b9641f
24
26
  with:
25
27
  token: ${{ secrets.CODECOV_TOKEN }}
@@ -10,10 +10,12 @@ name: copyrights
10
10
  pull_request:
11
11
  branches:
12
12
  - master
13
+ permissions:
14
+ contents: read
13
15
  jobs:
14
16
  copyrights:
15
17
  timeout-minutes: 15
16
18
  runs-on: ubuntu-24.04
17
19
  steps:
18
- - uses: actions/checkout@v6
19
- - uses: yegor256/copyrights-action@0.0.12
20
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
21
+ - uses: yegor256/copyrights-action@b4c048dcea8ece09cbe021a2a26139faf1885e44
@@ -11,6 +11,8 @@ name: markdown-lint
11
11
  branches:
12
12
  - master
13
13
  paths-ignore: ['paper/**', 'sandbox/**']
14
+ permissions:
15
+ contents: read
14
16
  concurrency:
15
17
  group: markdown-lint-${{ github.ref }}
16
18
  cancel-in-progress: true
@@ -19,5 +21,5 @@ jobs:
19
21
  timeout-minutes: 15
20
22
  runs-on: ubuntu-24.04
21
23
  steps:
22
- - uses: actions/checkout@v6
23
- - uses: DavidAnson/markdownlint-cli2-action@v24.0.0
24
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
25
+ - uses: DavidAnson/markdownlint-cli2-action@b847b0e2798e09594353ac3d92f6222621a4d870
@@ -10,10 +10,12 @@ name: pdd
10
10
  pull_request:
11
11
  branches:
12
12
  - master
13
+ permissions:
14
+ contents: read
13
15
  jobs:
14
16
  pdd:
15
17
  timeout-minutes: 15
16
18
  runs-on: ubuntu-24.04
17
19
  steps:
18
20
  - uses: actions/checkout@v6
19
- - uses: volodya-lombrozo/pdd-action@master
21
+ - uses: volodya-lombrozo/pdd-action@69842b56627431c5f232f5ea2dc2fca82f409c54
@@ -10,6 +10,8 @@ name: rake
10
10
  pull_request:
11
11
  branches:
12
12
  - master
13
+ permissions:
14
+ contents: read
13
15
  jobs:
14
16
  rake:
15
17
  strategy:
@@ -17,8 +19,8 @@ jobs:
17
19
  os: [ubuntu-24.04, macos-15]
18
20
  runs-on: ${{ matrix.os }}
19
21
  steps:
20
- - uses: actions/checkout@v6
21
- - uses: ruby/setup-ruby@v1
22
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
23
+ - uses: ruby/setup-ruby@d45b1a4e94b71acab930e56e79c6aa188764e7f9
22
24
  with:
23
25
  ruby-version: .ruby-version
24
26
  bundler-cache: true
@@ -10,10 +10,12 @@ name: reuse
10
10
  pull_request:
11
11
  branches:
12
12
  - master
13
+ permissions:
14
+ contents: read
13
15
  jobs:
14
16
  reuse:
15
17
  timeout-minutes: 15
16
18
  runs-on: ubuntu-24.04
17
19
  steps:
18
- - uses: actions/checkout@v6
19
- - uses: fsfe/reuse-action@v6
20
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
21
+ - uses: fsfe/reuse-action@772649cfa03a64a08c458c7cca9a6a473d74e7f9
@@ -10,12 +10,14 @@ name: typos
10
10
  pull_request:
11
11
  branches:
12
12
  - master
13
+ permissions:
14
+ contents: read
13
15
  jobs:
14
16
  typos:
15
17
  timeout-minutes: 15
16
18
  runs-on: ubuntu-24.04
17
19
  steps:
18
- - uses: actions/checkout@v6
19
- - uses: crate-ci/typos@v1.48.0
20
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
21
+ - uses: crate-ci/typos@dbe52f72499cd4ab666928e4d14ecfa9ddbb6852
20
22
  with:
21
23
  config: .github/.typos.toml
@@ -6,10 +6,12 @@ name: xcop
6
6
  'on':
7
7
  push:
8
8
  pull_request:
9
+ permissions:
10
+ contents: read
9
11
  jobs:
10
12
  xcop:
11
13
  timeout-minutes: 15
12
14
  runs-on: ubuntu-24.04
13
15
  steps:
14
16
  - uses: actions/checkout@v6
15
- - uses: g4s8/xcop-action@master
17
+ - uses: g4s8/xcop-action@4e93f123cab886ca8e481a737ee586bc9f02d228
@@ -10,12 +10,14 @@ name: yamllint
10
10
  pull_request:
11
11
  branches:
12
12
  - master
13
+ permissions:
14
+ contents: read
13
15
  jobs:
14
16
  yamllint:
15
17
  timeout-minutes: 15
16
18
  runs-on: ubuntu-24.04
17
19
  steps:
18
- - uses: actions/checkout@v6
19
- - uses: ibiqlik/action-yamllint@v3
20
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
21
+ - uses: ibiqlik/action-yamllint@ae1abb2821b567e96742aa776f7b62c9b6a26bc8
20
22
  with:
21
23
  config_file: .yamllint.yml
data/lib/fbe/award.rb CHANGED
@@ -192,7 +192,9 @@ class Fbe::Award
192
192
  when :gte
193
193
  to_val(@operands[0], bill) >= to_val(@operands[1], bill)
194
194
  when :div
195
- to_val(@operands[0], bill) / to_val(@operands[1], bill)
195
+ divisor = to_val(@operands[1], bill)
196
+ raise(Fbe::Error, 'Division by zero in award calculation') if divisor.zero?
197
+ to_val(@operands[0], bill) / divisor
196
198
  when :times
197
199
  to_val(@operands[0], bill) * to_val(@operands[1], bill)
198
200
  when :plus
data/lib/fbe/delete.rb CHANGED
@@ -33,8 +33,8 @@ def Fbe.delete(fact, *props, fb: Fbe.fb, id: '_id')
33
33
  next if props.include?(k)
34
34
  before[k] = fact[k]
35
35
  end
36
- fb.query("(eq #{id} #{i})").delete!
37
36
  fb.txn do |fbt|
37
+ fbt.query("(eq #{id} #{i})").delete!
38
38
  c = fbt.insert
39
39
  f = c
40
40
  while f.instance_variable_defined?(:@fact) || f.instance_variable_defined?(:@origin)
@@ -32,8 +32,8 @@ def Fbe.delete_one(fact, prop, value, fb: Fbe.fb, id: '_id')
32
32
  return if nv == before[prop]
33
33
  before[prop] = nv
34
34
  before.delete(prop) if nv.empty?
35
- fb.query("(eq #{id} #{i})").delete!
36
35
  fb.txn do |fbt|
36
+ fbt.query("(eq #{id} #{i})").delete!
37
37
  c = fbt.insert
38
38
  f = c
39
39
  while f.instance_variable_defined?(:@fact) || f.instance_variable_defined?(:@origin)
data/lib/fbe/fb.rb CHANGED
@@ -60,7 +60,7 @@ def Fbe.fb(fb: $fb, global: $global, options: $options, loog: $loog)
60
60
  ),
61
61
  loog
62
62
  ),
63
- timeout: 60
63
+ timeout: options.timeout || 60
64
64
  )
65
65
  end
66
66
  end
data/lib/fbe/iterate.rb CHANGED
@@ -330,7 +330,7 @@ class Fbe::Iterate
330
330
  rescue Fbe::OffQuota
331
331
  raise
332
332
  rescue StandardError => e
333
- raise(e.class, "Failure in repository ##{repo} at ##{nxt}: #{e.message}")
333
+ raise(Fbe::Error, "Failure in repository ##{repo} at ##{nxt}: #{e.message}")
334
334
  end
335
335
  end
336
336
  unless before[repo].is_a?(Integer)
data/lib/fbe/kill_if.rb CHANGED
@@ -20,5 +20,5 @@ def Fbe.kill_if(facts, fb: Fbe.fb, fid: '_id')
20
20
  ids << f[fid].first
21
21
  end
22
22
  return 0 if ids.empty?
23
- fb.query("(or #{ids.map { |id| "(eq #{fid} #{id})" }.join})").delete!
23
+ fb.query("(or #{ids.map { |id| "(eq #{fid} #{id})" }.join(' ')})").delete!
24
24
  end
@@ -73,6 +73,7 @@ class Fbe::Middleware::SqliteStore
73
73
  raise(ArgumentError, 'Cache min age can be nil or Integer > 0')
74
74
  end
75
75
  @minage = cache_min_age
76
+ @mutex = Mutex.new
76
77
  end
77
78
 
78
79
  # Read a value from the cache.
@@ -170,94 +171,99 @@ class Fbe::Middleware::SqliteStore
170
171
 
171
172
  private
172
173
 
173
- def perform(&) # rubocop:disable Metrics/AbcSize
174
- @db ||=
175
- SQLite3::Database.new(@path).tap do |d| # rubocop:disable Metrics/BlockLength
174
+ def perform(&)
175
+ @mutex.synchronize do
176
+ @db ||= init!
177
+ end
178
+ @db.transaction(&)
179
+ end
180
+
181
+ def init! # rubocop:disable Metrics/AbcSize
182
+ SQLite3::Database.new(@path).tap do |d| # rubocop:disable Metrics/BlockLength
183
+ d.transaction do |t|
184
+ t.execute('CREATE TABLE IF NOT EXISTS cache(key TEXT UNIQUE NOT NULL, value TEXT);')
185
+ t.execute('CREATE INDEX IF NOT EXISTS cache_key_idx ON cache(key);')
186
+ t.execute('CREATE TABLE IF NOT EXISTS meta(key TEXT UNIQUE NOT NULL, value TEXT);')
187
+ t.execute('CREATE INDEX IF NOT EXISTS meta_key_idx ON meta(key);')
188
+ t.execute("INSERT INTO meta(key, value) VALUES('version', ?) ON CONFLICT(key) DO NOTHING;", [@version])
189
+ end
190
+ if d.execute("SELECT 1 FROM pragma_table_info('cache') WHERE name = 'touched_at';").dig(0, 0) != 1
176
191
  d.transaction do |t|
177
- t.execute('CREATE TABLE IF NOT EXISTS cache(key TEXT UNIQUE NOT NULL, value TEXT);')
192
+ t.execute('ALTER TABLE cache ADD COLUMN touched_at TEXT;')
193
+ t.execute('UPDATE cache set touched_at = ?;', [Time.now.utc.iso8601])
194
+ t.execute('ALTER TABLE cache RENAME TO cache_old;')
195
+ t.execute(<<~SQL)
196
+ CREATE TABLE IF NOT EXISTS cache(
197
+ key TEXT UNIQUE NOT NULL, value TEXT, touched_at TEXT NOT NULL
198
+ );
199
+ SQL
200
+ t.execute('INSERT INTO cache SELECT * FROM cache_old;')
201
+ t.execute('DROP TABLE cache_old;')
178
202
  t.execute('CREATE INDEX IF NOT EXISTS cache_key_idx ON cache(key);')
179
- t.execute('CREATE TABLE IF NOT EXISTS meta(key TEXT UNIQUE NOT NULL, value TEXT);')
180
- t.execute('CREATE INDEX IF NOT EXISTS meta_key_idx ON meta(key);')
181
- t.execute("INSERT INTO meta(key, value) VALUES('version', ?) ON CONFLICT(key) DO NOTHING;", [@version])
203
+ t.execute('CREATE INDEX IF NOT EXISTS cache_touched_at_idx ON cache(touched_at);')
182
204
  end
183
- if d.execute("SELECT 1 FROM pragma_table_info('cache') WHERE name = 'touched_at';").dig(0, 0) != 1
184
- d.transaction do |t|
185
- t.execute('ALTER TABLE cache ADD COLUMN touched_at TEXT;')
186
- t.execute('UPDATE cache set touched_at = ?;', [Time.now.utc.iso8601])
187
- t.execute('ALTER TABLE cache RENAME TO cache_old;')
188
- t.execute(<<~SQL)
189
- CREATE TABLE IF NOT EXISTS cache(
190
- key TEXT UNIQUE NOT NULL, value TEXT, touched_at TEXT NOT NULL
191
- );
192
- SQL
193
- t.execute('INSERT INTO cache SELECT * FROM cache_old;')
194
- t.execute('DROP TABLE cache_old;')
195
- t.execute('CREATE INDEX IF NOT EXISTS cache_key_idx ON cache(key);')
196
- t.execute('CREATE INDEX IF NOT EXISTS cache_touched_at_idx ON cache(touched_at);')
197
- end
198
- d.execute('VACUUM;')
205
+ d.execute('VACUUM;')
206
+ end
207
+ if d.execute("SELECT 1 FROM pragma_table_info('cache') WHERE name = 'created_at';").dig(0, 0) != 1
208
+ d.transaction do |t|
209
+ t.execute('ALTER TABLE cache ADD COLUMN created_at TEXT;')
210
+ t.execute('UPDATE cache set created_at = ?;', [Time.now.utc.iso8601])
211
+ t.execute('ALTER TABLE cache RENAME TO cache_old;')
212
+ t.execute(<<~SQL)
213
+ CREATE TABLE IF NOT EXISTS cache(
214
+ key TEXT UNIQUE NOT NULL, value TEXT, touched_at TEXT NOT NULL, created_at TEXT NOT NULL
215
+ );
216
+ SQL
217
+ t.execute('INSERT INTO cache SELECT * FROM cache_old;')
218
+ t.execute('DROP TABLE cache_old;')
219
+ t.execute('CREATE INDEX IF NOT EXISTS cache_key_idx ON cache(key);')
220
+ t.execute('CREATE INDEX IF NOT EXISTS cache_touched_at_idx ON cache(touched_at);')
221
+ t.execute('CREATE INDEX IF NOT EXISTS cache_created_at_idx ON cache(created_at);')
199
222
  end
200
- if d.execute("SELECT 1 FROM pragma_table_info('cache') WHERE name = 'created_at';").dig(0, 0) != 1
201
- d.transaction do |t|
202
- t.execute('ALTER TABLE cache ADD COLUMN created_at TEXT;')
203
- t.execute('UPDATE cache set created_at = ?;', [Time.now.utc.iso8601])
204
- t.execute('ALTER TABLE cache RENAME TO cache_old;')
205
- t.execute(<<~SQL)
206
- CREATE TABLE IF NOT EXISTS cache(
207
- key TEXT UNIQUE NOT NULL, value TEXT, touched_at TEXT NOT NULL, created_at TEXT NOT NULL
208
- );
209
- SQL
210
- t.execute('INSERT INTO cache SELECT * FROM cache_old;')
211
- t.execute('DROP TABLE cache_old;')
212
- t.execute('CREATE INDEX IF NOT EXISTS cache_key_idx ON cache(key);')
213
- t.execute('CREATE INDEX IF NOT EXISTS cache_touched_at_idx ON cache(touched_at);')
214
- t.execute('CREATE INDEX IF NOT EXISTS cache_created_at_idx ON cache(created_at);')
215
- end
216
- d.execute('VACUUM;')
223
+ d.execute('VACUUM;')
224
+ end
225
+ found = d.execute("SELECT value FROM meta WHERE key = 'version' LIMIT 1;").dig(0, 0)
226
+ if found != @version
227
+ @loog.info("Version mismatch in SQLite cache: stored '#{found}' != current '#{@version}', cleaning up")
228
+ d.transaction do |t|
229
+ t.execute('DELETE FROM cache;')
230
+ t.execute("UPDATE meta SET value = ? WHERE key = 'version';", [@version])
217
231
  end
218
- found = d.execute("SELECT value FROM meta WHERE key = 'version' LIMIT 1;").dig(0, 0)
219
- if found != @version
220
- @loog.info("Version mismatch in SQLite cache: stored '#{found}' != current '#{@version}', cleaning up")
221
- d.transaction do |t|
222
- t.execute('DELETE FROM cache;')
223
- t.execute("UPDATE meta SET value = ? WHERE key = 'version';", [@version])
224
- end
225
- d.execute('VACUUM;')
232
+ d.execute('VACUUM;')
233
+ end
234
+ unless @ttl.nil?
235
+ d.transaction do |t|
236
+ t.execute(<<~SQL, [(Time.now.utc - (@ttl * 60 * 60)).iso8601])
237
+ DELETE FROM cache
238
+ WHERE key IN (SELECT key FROM cache WHERE (created_at < ?));
239
+ SQL
226
240
  end
227
- unless @ttl.nil?
241
+ d.execute('VACUUM;')
242
+ end
243
+ if File.size(@path) > @maxsize
244
+ @loog.info(
245
+ "SQLite cache file size (#{Filesize.from(File.size(@path).to_s).pretty} bytes) exceeds " \
246
+ "#{Filesize.from(@maxsize.to_s).pretty}, cleaning up old entries"
247
+ )
248
+ deleted = 0
249
+ while d.execute(<<~SQL).dig(0, 0) > @maxsize
250
+ SELECT (page_count - freelist_count) * page_size AS size
251
+ FROM pragma_page_count(), pragma_freelist_count(), pragma_page_size();
252
+ SQL
228
253
  d.transaction do |t|
229
- t.execute(<<~SQL, [(Time.now.utc - (@ttl * 60 * 60)).iso8601])
254
+ t.execute(<<~SQL)
230
255
  DELETE FROM cache
231
- WHERE key IN (SELECT key FROM cache WHERE (created_at < ?));
256
+ WHERE key IN (SELECT key FROM cache ORDER BY touched_at LIMIT 50)
232
257
  SQL
258
+ deleted += t.changes
233
259
  end
234
- d.execute('VACUUM;')
235
- end
236
- if File.size(@path) > @maxsize
237
- @loog.info(
238
- "SQLite cache file size (#{Filesize.from(File.size(@path).to_s).pretty} bytes) exceeds " \
239
- "#{Filesize.from(@maxsize.to_s).pretty}, cleaning up old entries"
240
- )
241
- deleted = 0
242
- while d.execute(<<~SQL).dig(0, 0) > @maxsize
243
- SELECT (page_count - freelist_count) * page_size AS size
244
- FROM pragma_page_count(), pragma_freelist_count(), pragma_page_size();
245
- SQL
246
- d.transaction do |t|
247
- t.execute(<<~SQL)
248
- DELETE FROM cache
249
- WHERE key IN (SELECT key FROM cache ORDER BY touched_at LIMIT 50)
250
- SQL
251
- deleted += t.changes
252
- end
253
- end
254
- d.execute('VACUUM;')
255
- @loog.info(
256
- "Deleted #{deleted} old cache entries, " \
257
- "new file size: #{Filesize.from(File.size(@path).to_s).pretty} bytes"
258
- )
259
260
  end
261
+ d.execute('VACUUM;')
262
+ @loog.info(
263
+ "Deleted #{deleted} old cache entries, " \
264
+ "new file size: #{Filesize.from(File.size(@path).to_s).pretty} bytes"
265
+ )
260
266
  end
261
- @db.transaction(&)
267
+ end
262
268
  end
263
269
  end
@@ -33,10 +33,11 @@ class Fbe::Middleware::Trace < Faraday::Middleware
33
33
  # @param [Array] trace The array to store trace entries
34
34
  # @param [Array<Symbol>] ignores The array of symbols (see Faraday::HttpCache::CACHE_STATUSES),
35
35
  # which will be ignored
36
- def initialize(app, trace, ignores: [])
36
+ def initialize(app, trace, ignores: [], mutex: Mutex.new)
37
37
  super(app)
38
38
  @trace = trace
39
39
  @ignores = ignores
40
+ @mutex = mutex
40
41
  end
41
42
 
42
43
  # Processes the HTTP request and records trace information.
@@ -54,7 +55,7 @@ class Fbe::Middleware::Trace < Faraday::Middleware
54
55
  entry[:status] = response_env.status
55
56
  entry[:finished_at] = finished
56
57
  entry[:duration] = duration
57
- @trace << entry
58
+ @mutex.synchronize { @trace << entry }
58
59
  end
59
60
  end
60
61
  end
data/lib/fbe/octo.rb CHANGED
@@ -56,6 +56,7 @@ def Fbe.octo(options: $options, global: $global, loog: $loog) # rubocop:disable
56
56
  begin
57
57
  loog.info("Fbe version is #{Fbe::VERSION}")
58
58
  trace = []
59
+ mutex = Mutex.new
59
60
  limits = {}
60
61
  if options.testing.nil?
61
62
  o = Octokit::Client.new
@@ -96,7 +97,7 @@ def Fbe.octo(options: $options, global: $global, loog: $loog) # rubocop:disable
96
97
  builder.use(Octokit::Response::RaiseError)
97
98
  builder.use(Faraday::Response::Logger, loog, formatter: Fbe::Middleware::Formatter)
98
99
  builder.use(Fbe::Middleware::RateLimit, limits)
99
- builder.use(Fbe::Middleware::Trace, trace, ignores: [:fresh])
100
+ builder.use(Fbe::Middleware::Trace, trace, ignores: [:fresh], mutex:)
100
101
  if options.sqlite_cache
101
102
  maxsize = Integer(Filesize.from(options.sqlite_cache_maxsize || '100M'))
102
103
  maxvsize = Integer(Filesize.from(options.sqlite_cache_maxvsize || '100K'))
@@ -129,36 +130,38 @@ def Fbe.octo(options: $options, global: $global, loog: $loog) # rubocop:disable
129
130
  o = Fbe::FakeOctokit.new
130
131
  end
131
132
  o =
132
- decoor(o, loog:, trace:, limits:) do # rubocop:disable Metrics/BlockLength
133
+ decoor(o, loog:, trace:, limits:, mutex:) do # rubocop:disable Metrics/BlockLength
133
134
  def print_trace!(all: false, max: 5)
134
- if @trace.empty?
135
- @loog.debug('GitHub API trace is empty')
136
- else
137
- grouped =
138
- @trace.select { |e| e[:duration] > 0.05 || all }.group_by do |entry|
139
- uri = URI.parse(entry[:url])
140
- query = uri.query
141
- query = "?#{query.ellipsized(40)}" if query
142
- "#{uri.scheme}://#{uri.host}#{uri.path}#{query}"
143
- end
144
- message = grouped
145
- .sort_by { |_path, entries| -entries.count }
146
- .map do |path, entries|
147
- [
148
- ' ',
149
- path.gsub(%r{^https://api.github.com/}, '/'),
150
- ': ',
151
- entries.count,
152
- " (#{entries.sum { |e| e[:duration] }.seconds})"
153
- ].join
154
- end
155
- .take(max)
156
- .join("\n")
157
- @loog.info(
158
- "GitHub API trace (#{grouped.count} URLs vs #{@trace.count} requests, " \
159
- "#{@origin.rate_limit!.remaining} quota left):\n#{message}"
160
- )
161
- @trace.clear
135
+ @mutex.synchronize do
136
+ if @trace.empty?
137
+ @loog.debug('GitHub API trace is empty')
138
+ else
139
+ grouped =
140
+ @trace.select { |e| e[:duration] > 0.05 || all }.group_by do |entry|
141
+ uri = URI.parse(entry[:url])
142
+ query = uri.query
143
+ query = "?#{query.ellipsized(40)}" if query
144
+ "#{uri.scheme}://#{uri.host}#{uri.path}#{query}"
145
+ end
146
+ message = grouped
147
+ .sort_by { |_path, entries| -entries.count }
148
+ .map do |path, entries|
149
+ [
150
+ ' ',
151
+ path.gsub(%r{^https://api.github.com/}, '/'),
152
+ ': ',
153
+ entries.count,
154
+ " (#{entries.sum { |e| e[:duration] }.seconds})"
155
+ ].join
156
+ end
157
+ .take(max)
158
+ .join("\n")
159
+ @loog.info(
160
+ "GitHub API trace (#{grouped.count} URLs vs #{@trace.count} requests, " \
161
+ "#{@origin.rate_limit!.remaining} quota left):\n#{message}"
162
+ )
163
+ @trace.clear
164
+ end
162
165
  end
163
166
  end
164
167
  def off_quota?(threshold: nil, resource: :core) # rubocop:disable Layout/EmptyLineBetweenDefs
data/lib/fbe/overwrite.rb CHANGED
@@ -65,8 +65,8 @@ def Fbe.overwrite(fact, property_or_hash, values = nil, fb: Fbe.fb, fid: '_id')
65
65
  end
66
66
  id = fact[fid]&.first
67
67
  raise(Fbe::Error, "There is no #{fid} in the fact, cannot use Fbe.overwrite") if id.nil?
68
- raise(Fbe::Error, "No facts by #{fid} = #{id}") if fb.query("(eq #{fid} #{id})").delete!.zero?
69
68
  fb.txn do |fbt|
69
+ raise(Fbe::Error, "No facts by #{fid} = #{id}") if fbt.query("(eq #{fid} #{id})").delete!.zero?
70
70
  n = fbt.insert
71
71
  f = n
72
72
  while f.instance_variable_defined?(:@fact) || f.instance_variable_defined?(:@origin)
@@ -101,8 +101,8 @@ def Fbe.overwrite(fact, property_or_hash, values = nil, fb: Fbe.fb, fid: '_id')
101
101
  end
102
102
  id = fact[fid]&.first
103
103
  raise(Fbe::Error, "There is no #{fid} in the fact, cannot use Fbe.overwrite") if id.nil?
104
- raise(Fbe::Error, "No facts by #{fid} = #{id}") if fb.query("(eq #{fid} #{id})").delete!.zero?
105
104
  fb.txn do |fbt|
105
+ raise(Fbe::Error, "No facts by #{fid} = #{id}") if fbt.query("(eq #{fid} #{id})").delete!.zero?
106
106
  n = fbt.insert
107
107
  f = n
108
108
  while f.instance_variable_defined?(:@fact) || f.instance_variable_defined?(:@origin)
data/lib/fbe.rb CHANGED
@@ -9,6 +9,6 @@
9
9
  # Copyright:: Copyright (c) 2024-2026 Zerocracy
10
10
  # License:: MIT
11
11
  module Fbe
12
- VERSION = '0.49.0' unless const_defined?(:VERSION)
12
+ VERSION = '0.49.1' unless const_defined?(:VERSION)
13
13
  class Error < StandardError; end
14
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fbe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.49.0
4
+ version: 0.49.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko