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 +4 -4
- data/.github/workflows/actionlint.yml +4 -2
- data/.github/workflows/codecov.yml +5 -3
- data/.github/workflows/copyrights.yml +4 -2
- data/.github/workflows/markdown-lint.yml +4 -2
- data/.github/workflows/pdd.yml +3 -1
- data/.github/workflows/rake.yml +4 -2
- data/.github/workflows/reuse.yml +4 -2
- data/.github/workflows/typos.yml +4 -2
- data/.github/workflows/xcop.yml +3 -1
- data/.github/workflows/yamllint.yml +4 -2
- data/lib/fbe/award.rb +3 -1
- data/lib/fbe/delete.rb +1 -1
- data/lib/fbe/delete_one.rb +1 -1
- data/lib/fbe/fb.rb +1 -1
- data/lib/fbe/iterate.rb +1 -1
- data/lib/fbe/kill_if.rb +1 -1
- data/lib/fbe/middleware/sqlite_store.rb +83 -77
- data/lib/fbe/middleware/trace.rb +3 -2
- data/lib/fbe/octo.rb +33 -30
- data/lib/fbe/overwrite.rb +2 -2
- data/lib/fbe.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8b2279330d7d5bfd9b1f0cd264e1922af79eb601fe2cb7d006cb9f0ace259b90
|
|
4
|
+
data.tar.gz: 6dcbf736f483cf44bb7ee4b5c0a265559e7a64f911eac7f50b598b01eb457940
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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@
|
|
19
|
-
- uses: reviewdog/action-actionlint@
|
|
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@
|
|
16
|
-
- uses: ruby/setup-ruby@
|
|
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@
|
|
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@
|
|
19
|
-
- uses: yegor256/copyrights-action@
|
|
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@
|
|
23
|
-
- uses: DavidAnson/markdownlint-cli2-action@
|
|
24
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
|
|
25
|
+
- uses: DavidAnson/markdownlint-cli2-action@b847b0e2798e09594353ac3d92f6222621a4d870
|
data/.github/workflows/pdd.yml
CHANGED
|
@@ -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@
|
|
21
|
+
- uses: volodya-lombrozo/pdd-action@69842b56627431c5f232f5ea2dc2fca82f409c54
|
data/.github/workflows/rake.yml
CHANGED
|
@@ -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@
|
|
21
|
-
- uses: ruby/setup-ruby@
|
|
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
|
data/.github/workflows/reuse.yml
CHANGED
|
@@ -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@
|
|
19
|
-
- uses: fsfe/reuse-action@
|
|
20
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
|
|
21
|
+
- uses: fsfe/reuse-action@772649cfa03a64a08c458c7cca9a6a473d74e7f9
|
data/.github/workflows/typos.yml
CHANGED
|
@@ -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@
|
|
19
|
-
- uses: crate-ci/typos@
|
|
20
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
|
|
21
|
+
- uses: crate-ci/typos@dbe52f72499cd4ab666928e4d14ecfa9ddbb6852
|
|
20
22
|
with:
|
|
21
23
|
config: .github/.typos.toml
|
data/.github/workflows/xcop.yml
CHANGED
|
@@ -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@
|
|
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@
|
|
19
|
-
- uses: ibiqlik/action-yamllint@
|
|
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
|
-
|
|
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)
|
data/lib/fbe/delete_one.rb
CHANGED
|
@@ -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
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(
|
|
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
|
@@ -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(&)
|
|
174
|
-
@
|
|
175
|
-
|
|
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('
|
|
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
|
|
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
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
-
|
|
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
|
|
254
|
+
t.execute(<<~SQL)
|
|
230
255
|
DELETE FROM cache
|
|
231
|
-
WHERE key IN (SELECT key FROM cache
|
|
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
|
-
|
|
267
|
+
end
|
|
262
268
|
end
|
|
263
269
|
end
|
data/lib/fbe/middleware/trace.rb
CHANGED
|
@@ -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
|
-
|
|
135
|
-
@
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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