file_keys: fill in the background, use it once complete
Copying all existing keys in the migration read the files rows from the HDD for over half an hour and held up the deploy. gc:scheduler now copies them in slices (FILE_KEYS_FILL_SECONDS per sweep) and FileStore checks every partition until the fill is complete. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
693e6c3244
commit
f0ff8e200f
8 files changed
+163
-18
No files matched your search
@@ -0,0 +1,41 @@
|
||||
import { test } from '@japa/runner'
|
||||
import db from '@adonisjs/lucid/services/db'
|
||||
import testUtils from '@adonisjs/core/services/test_utils'
|
||||
import FileKeys from '#services/FileKeys'
|
||||
import FileStore from '#services/FileStore'
|
||||
|
||||
const file = (key: string, name: string) => {
|
||||
const now = new Date()
|
||||
return { file_key: key, filename: name, poster: 'x', date: now.getTime(), parts: 1, groups: '[]', segments: [], created_at: now, updated_at: now }
|
||||
}
|
||||
|
||||
test.group('file_keys', (group) => {
|
||||
group.each.setup(() => testUtils.db().withGlobalTransaction())
|
||||
group.each.teardown(() => FileKeys.forget())
|
||||
|
||||
test('the fill copies keys from before, then file inserts use the filter', async ({ assert }) => {
|
||||
// A file from before file_keys: in files, not in file_keys.
|
||||
const [old] = await FileStore.insert([file('fk-old'.padEnd(40, '0'), 'old.bin')])
|
||||
await db.rawQuery(`DELETE FROM file_keys WHERE key_hash = hashtextextended(?, 0)`, ['fk-old'.padEnd(40, '0')])
|
||||
await db.from('file_keys_fill').where('id', 1).update({ next_id: 0, until_id: null, complete: false })
|
||||
FileKeys.forget()
|
||||
|
||||
// Not complete: every partition is checked, so the old key is found anyway.
|
||||
assert.isFalse(await FileKeys.complete())
|
||||
assert.lengthOf(await FileStore.insert([file('fk-old'.padEnd(40, '0'), 'again.bin')]), 0)
|
||||
|
||||
const filled = await FileKeys.fill(60_000)
|
||||
assert.isTrue(filled.complete)
|
||||
assert.isAtLeast(filled.untilId, old.id)
|
||||
const [{ n }] = (await db.rawQuery(`SELECT count(*) AS n FROM file_keys WHERE key_hash = hashtextextended(?, 0)`, ['fk-old'.padEnd(40, '0')])).rows
|
||||
assert.equal(Number(n), 1)
|
||||
|
||||
// Complete: the filter says the old key may exist, the partitions confirm it; a new key goes in.
|
||||
assert.isTrue(await FileKeys.complete())
|
||||
assert.lengthOf(await FileStore.insert([file('fk-old'.padEnd(40, '0'), 'again.bin')]), 0)
|
||||
assert.lengthOf(await FileStore.insert([file('fk-new'.padEnd(40, '0'), 'new.bin')]), 1)
|
||||
// And the trigger put the new one in file_keys.
|
||||
const [{ m }] = (await db.rawQuery(`SELECT count(*) AS m FROM file_keys WHERE key_hash = hashtextextended(?, 0)`, ['fk-new'.padEnd(40, '0')])).rows
|
||||
assert.equal(Number(m), 1)
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user