mirror of
https://codeberg.org/timelimit/timelimit-server.git
synced 2026-08-31 19:03:45 +02:00
128 lines
3.5 KiB
TypeScript
128 lines
3.5 KiB
TypeScript
/*
|
|
* server component for the TimeLimit App
|
|
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, version 3 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import { uniqBy } from 'lodash'
|
|
import * as Sequelize from 'sequelize'
|
|
import { Database } from '../database'
|
|
import { generateVersionId } from '../util/token'
|
|
|
|
export function initDeleteOldUsedTimesWorker ({ database }: {
|
|
database: Database
|
|
}) {
|
|
function doWorkSafe () {
|
|
deleteOldUsedTimes({ database }).catch((ex) => {
|
|
console.warn('error deleting old used times', ex)
|
|
})
|
|
}
|
|
|
|
setTimeout(() => {
|
|
doWorkSafe()
|
|
|
|
setInterval(() => {
|
|
doWorkSafe()
|
|
}, 1000 * 60 * 30 /* every 30 minutes */)
|
|
}, 1000 * 60 * 13 /* after 13 minutes */)
|
|
}
|
|
|
|
async function deleteOldUsedTimes ({ database }: {
|
|
database: Database
|
|
}) {
|
|
const now = Date.now()
|
|
|
|
await database.transaction(async (transaction) => {
|
|
// get matching categories
|
|
const categoriesToCleanUpOne = await database.usedTime.findAll({
|
|
transaction,
|
|
where: {
|
|
lastUpdate: {
|
|
[Sequelize.Op.lt]: (now - 1000 * 60 * 60 * 24 * 10 /* 10 days */).toString()
|
|
}
|
|
},
|
|
attributes: [
|
|
'familyId',
|
|
'categoryId'
|
|
],
|
|
limit: 1000,
|
|
order: [['lastUpdate', 'ASC']]
|
|
}).map((item) => ({
|
|
familyId: item.familyId,
|
|
categoryId: item.categoryId
|
|
}))
|
|
|
|
const categoriesToCleanUpTwo = await database.sessionDuration.findAll({
|
|
transaction,
|
|
where: {
|
|
roundedLastUpdate: {
|
|
[Sequelize.Op.lt]: (now - 1000 * 60 * 60 * 24 * 3 /* 3 days */).toString()
|
|
}
|
|
},
|
|
attributes: [
|
|
'familyId',
|
|
'categoryId'
|
|
],
|
|
limit: 1000,
|
|
order: [['roundedLastUpdate', 'ASC']]
|
|
}).map((item) => ({
|
|
familyId: item.familyId,
|
|
categoryId: item.categoryId
|
|
}))
|
|
|
|
const categoriesToCleanUp = [ ...categoriesToCleanUpOne, ...categoriesToCleanUpTwo ]
|
|
|
|
const distinctCategoriesToCleanUp = uniqBy(categoriesToCleanUp, (item) => item.familyId + '_' + item.categoryId)
|
|
|
|
if (distinctCategoriesToCleanUp.length > 0) {
|
|
// delete old items of matching categories
|
|
await database.usedTime.destroy({
|
|
transaction,
|
|
where: {
|
|
[Sequelize.Op.or]: (
|
|
distinctCategoriesToCleanUp
|
|
),
|
|
lastUpdate: {
|
|
[Sequelize.Op.lt]: (now - 1000 * 60 * 60 * 24 * 10 /* 10 days */).toString()
|
|
}
|
|
}
|
|
})
|
|
|
|
await database.sessionDuration.destroy({
|
|
transaction,
|
|
where: {
|
|
[Sequelize.Op.or]: (
|
|
distinctCategoriesToCleanUp
|
|
),
|
|
roundedLastUpdate: {
|
|
[Sequelize.Op.lt]: (now - 1000 * 60 * 60 * 24 * 3 /* 3 days */).toString()
|
|
}
|
|
}
|
|
})
|
|
|
|
// invalidiate categories
|
|
await database.category.update({
|
|
usedTimesVersion: generateVersionId()
|
|
}, {
|
|
transaction,
|
|
where: {
|
|
[Sequelize.Op.or]: (
|
|
distinctCategoriesToCleanUp
|
|
)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|