mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-04 21:08:09 +03:00
Create Import Locks
This commit is contained in:
Generated
+3
-3
@@ -80,7 +80,7 @@ dependencies:
|
||||
rate-limit-redis: 2.1.0
|
||||
redis: 3.1.2
|
||||
rimraf: 3.0.2
|
||||
tachi-common: github.com/zkldi/tachi-common/137fb72499a2ee6a98791ffea3961d0c69bf24b7
|
||||
tachi-common: github.com/zkldi/tachi-common/fff6217ee6c483f773fed97848802a774e8c5b70
|
||||
typescript: 4.3.2
|
||||
winston: 3.3.3
|
||||
|
||||
@@ -4445,8 +4445,8 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
github.com/zkldi/tachi-common/137fb72499a2ee6a98791ffea3961d0c69bf24b7:
|
||||
resolution: {tarball: https://codeload.github.com/zkldi/tachi-common/tar.gz/137fb72499a2ee6a98791ffea3961d0c69bf24b7}
|
||||
github.com/zkldi/tachi-common/fff6217ee6c483f773fed97848802a774e8c5b70:
|
||||
resolution: {tarball: https://codeload.github.com/zkldi/tachi-common/tar.gz/fff6217ee6c483f773fed97848802a774e8c5b70}
|
||||
name: kamaitachi-common
|
||||
version: 0.1.0
|
||||
dependencies:
|
||||
|
||||
Vendored
+2
@@ -24,6 +24,7 @@ import {
|
||||
PBScoreDocument,
|
||||
UserMilestoneDocument,
|
||||
BMSCourseDocument,
|
||||
ImportLockDocument,
|
||||
} from "tachi-common";
|
||||
import monk from "monk";
|
||||
import { MONGO_BASE_URL } from "../../lib/setup/config";
|
||||
@@ -132,6 +133,7 @@ const db = {
|
||||
"bms-course-lookup": monkDB.get<BMSCourseDocument>("bms-course-lookup"),
|
||||
"api-tokens": monkDB.get<APITokenDocument>("api-tokens"),
|
||||
"orphan-scores": monkDB.get<OrphanScoreDocument>("orphan-scores"),
|
||||
"import-locks": monkDB.get<ImportLockDocument>("import-locks"),
|
||||
};
|
||||
|
||||
export default db;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import db from "../../../../external/mongo/db";
|
||||
import { integer } from "tachi-common";
|
||||
|
||||
/**
|
||||
* Gets a users "import lock" if one exists. If one does not exist, it is set.
|
||||
* @param userID - The user this import lock is for.
|
||||
* @returns If no lock exists for this user (and one was created), undefined is returned
|
||||
* If a lock exists for the user, the lock is returned.
|
||||
*/
|
||||
export function GetOrSetUserLock(userID: integer) {
|
||||
return db["import-locks"].findOneAndUpdate(
|
||||
{
|
||||
userID,
|
||||
},
|
||||
{
|
||||
userID,
|
||||
},
|
||||
{
|
||||
upsert: true,
|
||||
returnDocument: "before",
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a users import lock.
|
||||
*/
|
||||
export function RemoveUserLock(userID: integer) {
|
||||
return db["import-locks"].remove({
|
||||
userID,
|
||||
});
|
||||
}
|
||||
@@ -22,6 +22,8 @@ import { ConverterFunction, ImportInputParser } from "../import-types/common/typ
|
||||
import { ScorePlaytypeMap } from "./common/types";
|
||||
import { Converters } from "../import-types/converters";
|
||||
import { ClassHandler } from "./user-game-stats/types";
|
||||
import { GetOrSetUserLock, RemoveUserLock } from "./import-locks/lock";
|
||||
import ScoreImportFatalError from "./score-importing/score-import-error";
|
||||
|
||||
/**
|
||||
* Performs a Score Import.
|
||||
@@ -33,6 +35,21 @@ export default async function ScoreImportMain<D, C>(
|
||||
InputParser: ImportInputParser<D, C>,
|
||||
providedImportObjects?: { logger: KtLogger; importID: string }
|
||||
) {
|
||||
const lock = await GetOrSetUserLock(user.id);
|
||||
|
||||
if (lock) {
|
||||
// @danger
|
||||
// Throwing away an import if the user already has one outgoing is *bad*, as in the case
|
||||
// of degraded performance we might just start throwing scores away. This is obviously
|
||||
// not great, but any other solution involves making a queue, which can't be done because
|
||||
// InputParser is a very dynamic function that cannot be stored in redis or something.
|
||||
//
|
||||
// Under normal circumstances, there is no scenario where a user would have two ongoing
|
||||
// imports at the same time - even if they were using single-score imports on a 5 second
|
||||
// chart, as each score import takes only around ~10-15miliseconds.
|
||||
throw new ScoreImportFatalError(409, "This user already has an ongoing import.");
|
||||
}
|
||||
|
||||
const timeStarted = Date.now();
|
||||
let importID;
|
||||
let logger;
|
||||
@@ -202,6 +219,8 @@ export default async function ScoreImportMain<D, C>(
|
||||
},
|
||||
});
|
||||
|
||||
await RemoveUserLock(user.id);
|
||||
|
||||
return ImportDocument;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
Reference in New Issue
Block a user