pinafore/routes/_database/cleanup.js

151 lines
4.3 KiB
JavaScript
Raw Normal View History

2018-02-14 03:34:37 +00:00
import { dbPromise, getDatabase } from './databaseLifecycle'
import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
import {
ACCOUNTS_STORE,
NOTIFICATION_TIMELINES_STORE,
NOTIFICATIONS_STORE,
2018-03-09 07:18:18 +00:00
PINNED_STATUSES_STORE,
2018-02-14 03:34:37 +00:00
RELATIONSHIPS_STORE,
STATUS_TIMELINES_STORE,
STATUSES_STORE,
2018-03-09 02:31:59 +00:00
THREADS_STORE,
2018-02-14 03:34:37 +00:00
TIMESTAMP
} from './constants'
import debounce from 'lodash/debounce'
import { store } from '../_store/store'
import { mark, stop } from '../_utils/marks'
const BATCH_SIZE = 20
const TIME_AGO = 14 * 24 * 60 * 60 * 1000 // two weeks ago
const DELAY = 5 * 60 * 1000 // five minutes
2018-02-14 03:35:46 +00:00
function batchedGetAll (callGetAll, callback) {
function nextBatch () {
2018-02-14 03:34:37 +00:00
callGetAll().onsuccess = function (e) {
let results = e.target.result
callback(results)
if (results.length) {
nextBatch()
}
}
}
nextBatch()
}
2018-03-09 02:31:59 +00:00
function cleanupStatuses (statusesStore, statusTimelinesStore, threadsStore, cutoff) {
2018-02-14 03:34:37 +00:00
batchedGetAll(
() => statusesStore.index(TIMESTAMP).getAll(IDBKeyRange.upperBound(cutoff), BATCH_SIZE),
results => {
results.forEach(result => {
statusesStore.delete(result.id)
2018-03-09 02:31:59 +00:00
threadsStore.delete(result.id)
2018-03-09 07:18:18 +00:00
let req = statusTimelinesStore.index('statusId').getAllKeys(IDBKeyRange.only(result.id))
2018-02-14 03:34:37 +00:00
req.onsuccess = e => {
2018-03-09 07:18:18 +00:00
let keys = e.target.result
keys.forEach(key => {
statusTimelinesStore.delete(key)
2018-02-14 03:34:37 +00:00
})
}
})
}
)
}
2018-02-14 03:35:46 +00:00
function cleanupNotifications (notificationsStore, notificationTimelinesStore, cutoff) {
2018-02-14 03:34:37 +00:00
batchedGetAll(
() => notificationsStore.index(TIMESTAMP).getAll(IDBKeyRange.upperBound(cutoff), BATCH_SIZE),
results => {
results.forEach(result => {
notificationsStore.delete(result.id)
2018-03-09 07:18:18 +00:00
let req = notificationTimelinesStore.index('notificationId').getAllKeys(IDBKeyRange.only(result.id))
2018-02-14 03:34:37 +00:00
req.onsuccess = e => {
2018-03-09 07:18:18 +00:00
let keys = e.target.result
keys.forEach(key => {
notificationTimelinesStore.delete(key)
2018-02-14 03:34:37 +00:00
})
}
})
}
)
}
2018-03-09 07:18:18 +00:00
function cleanupAccounts (accountsStore, pinnedStatusesStore, cutoff) {
2018-02-14 03:34:37 +00:00
batchedGetAll(
() => accountsStore.index(TIMESTAMP).getAll(IDBKeyRange.upperBound(cutoff), BATCH_SIZE),
(results) => {
results.forEach(result => {
accountsStore.delete(result.id)
2018-03-09 07:18:18 +00:00
let keyRange = IDBKeyRange.bound(result.id + '\u0000', result.id + '\u0000\uffff')
let req = pinnedStatusesStore.getAllKeys(keyRange)
req.onsuccess = e => {
let keys = e.target.result
keys.forEach(key => {
pinnedStatusesStore.delete(key)
})
}
2018-02-14 03:34:37 +00:00
})
}
)
}
2018-02-14 03:35:46 +00:00
function cleanupRelationships (relationshipsStore, cutoff) {
2018-02-14 03:34:37 +00:00
batchedGetAll(
() => relationshipsStore.index(TIMESTAMP).getAll(IDBKeyRange.upperBound(cutoff), BATCH_SIZE),
(results) => {
results.forEach(result => {
relationshipsStore.delete(result.id)
})
}
)
}
2018-02-14 03:35:46 +00:00
async function cleanup (instanceName) {
2018-02-14 03:34:37 +00:00
console.log('cleanup', instanceName)
mark(`cleanup:${instanceName}`)
let db = await getDatabase(instanceName)
let storeNames = [
STATUSES_STORE,
STATUS_TIMELINES_STORE,
NOTIFICATIONS_STORE,
NOTIFICATION_TIMELINES_STORE,
ACCOUNTS_STORE,
2018-03-09 02:31:59 +00:00
RELATIONSHIPS_STORE,
2018-03-09 07:18:18 +00:00
THREADS_STORE,
PINNED_STATUSES_STORE
2018-02-14 03:34:37 +00:00
]
await dbPromise(db, storeNames, 'readwrite', (stores) => {
let [
statusesStore,
statusTimelinesStore,
notificationsStore,
notificationTimelinesStore,
accountsStore,
2018-03-09 02:31:59 +00:00
relationshipsStore,
2018-03-09 07:18:18 +00:00
threadsStore,
pinnedStatusesStore
2018-02-14 03:34:37 +00:00
] = stores
let cutoff = Date.now() - TIME_AGO
2018-03-09 02:31:59 +00:00
cleanupStatuses(statusesStore, statusTimelinesStore, threadsStore, cutoff)
2018-02-14 03:34:37 +00:00
cleanupNotifications(notificationsStore, notificationTimelinesStore, cutoff)
2018-03-09 07:18:18 +00:00
cleanupAccounts(accountsStore, pinnedStatusesStore, cutoff)
2018-02-14 03:34:37 +00:00
cleanupRelationships(relationshipsStore, cutoff)
})
stop(`cleanup:${instanceName}`)
}
2018-02-14 03:35:46 +00:00
function doCleanup (instanceName) {
2018-02-14 03:34:37 +00:00
scheduleIdleTask(() => cleanup(instanceName))
}
function scheduledCleanup () {
console.log('scheduledCleanup')
let instances = store.get('loggedInInstancesInOrder')
for (let instance of instances) {
doCleanup(instance)
}
}
2018-02-14 03:35:46 +00:00
export const scheduleCleanup = debounce(() => scheduleIdleTask(scheduledCleanup), DELAY)