Files
usenet-indexer/tests/functional/file_partitions.spec.ts
T
Daan MeijerandClaude Opus 5.5 f8ee7e8662
Test and deploy / test (push) Successful in 1m59s
Test and deploy / deploy (push) Successful in 2m37s
files partitions: no deadlock, four ahead, and a failure no longer stops the GC sweep
Creating a partition deadlocked with file inserts 11 times in an hour, and
each failure ended the GC sweep before its deletes. The parent is now
locked first (lock_timeout 10 s), four partitions are kept ahead, and an
error is logged while the sweep goes on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 15:17:53 +02:00

52 lines
2.7 KiB
TypeScript

import { test } from '@japa/runner'
import db from '@adonisjs/lucid/services/db'
import testUtils from '@adonisjs/core/services/test_utils'
import FileStore from '#services/FileStore'
import FilePartitions, { FILE_PARTITION_SIZE } from '#services/FilePartitions'
const file = (fileKey: string, name: string) => {
const now = new Date()
return { file_key: fileKey, filename: name, poster: 'p', date: now.getTime(), parts: 1, size: 1, groups: '[]', segments: [], created_at: now, updated_at: now }
}
test.group('files partitions', (group) => {
group.each.setup(() => testUtils.db().withGlobalTransaction())
// Sequences ignore rollbacks: put files_id_seq back after each test.
group.each.setup(async () => {
const { rows } = await db.rawQuery(`SELECT last_value, is_called FROM files_id_seq`)
return async () => {
await db.rawQuery(`SELECT setval('files_id_seq', ?, ?)`, [rows[0].last_value, rows[0].is_called])
}
})
test('a file_key already in an older partition is not inserted again', async ({ assert }) => {
await db.rawQuery(`SELECT setval('files_id_seq', 500000, false)`)
const [first] = await FileStore.insert([file('k'.repeat(40), 'old.bin')])
// The next ids fall in the second partition, whose own unique index doesn't know the key.
await db.rawQuery(`SELECT setval('files_id_seq', 1000000, false)`)
const again = await FileStore.insert([file('k'.repeat(40), 'again.bin'), file('n'.repeat(40), 'new.bin'), file('n'.repeat(40), 'twice.bin')])
assert.deepEqual(again.map((f) => f.filename), ['new.bin'])
assert.isAtLeast(again[0].id, 1000000)
assert.equal(await db.from('files').where('file_key', 'k'.repeat(40)).count('* as n').then((r) => Number(r[0].n)), 1)
assert.isBelow(first.id, 1000000)
})
test('partitions are kept ready ahead of the newest id', async ({ assert }) => {
const upper = async () => {
const { rows } = await db.rawQuery(
`SELECT max((regexp_match(pg_get_expr(c.relpartbound, c.oid), 'TO \\(''{0,1}(\\d+)''{0,1}\\)'))[1]::bigint) AS upper
FROM pg_inherits i JOIN pg_class c ON c.oid = i.inhrelid WHERE i.inhparent = 'files'::regclass`
)
return Number(rows[0].upper)
}
await FilePartitions.ensure()
const before = await upper()
assert.deepEqual(await FilePartitions.ensure(), [])
// Ids handed out up to just inside the four partitions kept ahead: one more is needed.
await db.rawQuery(`SELECT setval('files_id_seq', ?, false)`, [before - 4 * FILE_PARTITION_SIZE + 10])
await FileStore.insert([file('e'.repeat(40), 'late.bin')])
assert.deepEqual(await FilePartitions.ensure(), [`files_p${before}`])
assert.equal(await upper(), before + FILE_PARTITION_SIZE)
})
})