1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00
pigallery2/benchmark/BenchmarkRunner.ts

239 lines
7.8 KiB
TypeScript
Raw Normal View History

2020-12-31 04:13:19 +08:00
import {Config} from '../src/common/config/private/Config';
import {ObjectManagers} from '../src/backend/model/ObjectManagers';
import {DiskMangerWorker} from '../src/backend/model/threading/DiskMangerWorker';
import {IndexingManager} from '../src/backend/model/database/sql/IndexingManager';
2020-12-31 04:54:07 +08:00
import * as path from 'path';
2021-01-04 17:32:19 +08:00
import * as fs from 'fs';
2020-12-31 04:13:19 +08:00
import {SearchTypes} from '../src/common/entities/AutoCompleteItem';
import {Utils} from '../src/common/Utils';
import {DirectoryDTO} from '../src/common/entities/DirectoryDTO';
import {ServerConfig} from '../src/common/config/private/PrivateConfig';
import {ProjectPath} from '../src/backend/ProjectPath';
import {Benchmark} from './Benchmark';
import {IndexingJob} from '../src/backend/model/jobs/jobs/IndexingJob';
import {IJob} from '../src/backend/model/jobs/jobs/IJob';
import {JobProgressStates} from '../src/common/entities/job/JobProgressDTO';
import {JobProgress} from '../src/backend/model/jobs/jobs/JobProgress';
import {ContentWrapper} from '../src/common/entities/ConentWrapper';
2020-12-31 04:54:07 +08:00
import {GalleryManager} from '../src/backend/model/database/sql/GalleryManager';
import {PersonManager} from '../src/backend/model/database/sql/PersonManager';
2020-12-31 19:35:28 +08:00
import {GalleryRouter} from '../src/backend/routes/GalleryRouter';
import {Express} from 'express';
import {PersonRouter} from '../src/backend/routes/PersonRouter';
import {QueryParams} from '../src/common/QueryParams';
2020-12-31 04:13:19 +08:00
export interface BenchmarkResult {
name: string;
duration: number;
contentWrapper?: ContentWrapper;
items?: number;
subBenchmarks?: BenchmarkResult[];
}
export class BMIndexingManager extends IndexingManager {
public async saveToDB(scannedDirectory: DirectoryDTO): Promise<void> {
return super.saveToDB(scannedDirectory);
}
}
2020-12-31 19:35:28 +08:00
class BMGalleryRouter extends GalleryRouter {
public static addDirectoryList(app: Express) {
GalleryRouter.addDirectoryList(app);
}
public static addSearch(app: Express) {
GalleryRouter.addSearch(app);
}
public static addInstantSearch(app: Express) {
GalleryRouter.addInstantSearch(app);
}
public static addAutoComplete(app: Express) {
GalleryRouter.addAutoComplete(app);
}
}
class BMPersonRouter extends PersonRouter {
public static addGetPersons(app: Express) {
PersonRouter.addGetPersons(app);
}
}
2020-12-31 04:13:19 +08:00
export class BenchmarkRunner {
2020-12-31 04:54:07 +08:00
inited = false;
2020-12-31 19:35:28 +08:00
private biggestDirPath: string = null;
private readonly requestTemplate: any = {
requestPipe: null,
params: {},
query: {},
session: {}
};
2020-12-31 04:13:19 +08:00
constructor(public RUNS: number) {
2020-12-31 19:35:28 +08:00
Config.Client.authenticationRequired = false;
2020-12-31 04:13:19 +08:00
}
async bmSaveDirectory(): Promise<BenchmarkResult> {
2020-12-31 04:54:07 +08:00
await this.init();
2020-12-31 04:13:19 +08:00
await this.resetDB();
2020-12-31 19:35:28 +08:00
const dir = await DiskMangerWorker.scanDirectory(this.biggestDirPath);
2020-12-31 04:13:19 +08:00
const bm = new Benchmark('Saving directory to DB', null, () => this.resetDB());
bm.addAStep({
name: 'Saving directory to DB',
fn: () => {
const im = new BMIndexingManager();
return im.saveToDB(dir);
}
});
return await bm.run(this.RUNS);
}
async bmScanDirectory(): Promise<BenchmarkResult> {
2020-12-31 04:54:07 +08:00
await this.init();
2020-12-31 04:13:19 +08:00
const bm = new Benchmark('Scanning directory');
bm.addAStep({
name: 'Scanning directory',
2020-12-31 19:35:28 +08:00
fn: async () => new ContentWrapper(await DiskMangerWorker.scanDirectory(this.biggestDirPath))
2020-12-31 04:13:19 +08:00
});
return await bm.run(this.RUNS);
}
async bmListDirectory(): Promise<BenchmarkResult> {
2021-01-04 17:32:19 +08:00
Config.Server.Indexing.reIndexingSensitivity = ServerConfig.ReIndexingSensitivity.low;
2020-12-31 04:54:07 +08:00
await this.init();
2020-12-31 04:13:19 +08:00
await this.setupDB();
2020-12-31 19:35:28 +08:00
const req = Utils.clone(this.requestTemplate);
req.params.directory = this.biggestDirPath;
const bm = new Benchmark('List directory', req,
2020-12-31 04:13:19 +08:00
async () => {
await ObjectManagers.reset();
await ObjectManagers.InitSQLManagers();
});
2020-12-31 19:35:28 +08:00
BMGalleryRouter.addDirectoryList(bm.BmExpressApp);
2020-12-31 04:13:19 +08:00
return await bm.run(this.RUNS);
}
async bmListPersons(): Promise<BenchmarkResult> {
await this.setupDB();
Config.Server.Indexing.reIndexingSensitivity = ServerConfig.ReIndexingSensitivity.low;
2020-12-31 19:35:28 +08:00
const bm = new Benchmark('Listing Faces', Utils.clone(this.requestTemplate), async () => {
2020-12-31 04:13:19 +08:00
await ObjectManagers.reset();
await ObjectManagers.InitSQLManagers();
});
2020-12-31 19:35:28 +08:00
BMPersonRouter.addGetPersons(bm.BmExpressApp);
2020-12-31 04:13:19 +08:00
return await bm.run(this.RUNS);
}
async bmAllSearch(text: string): Promise<{ result: BenchmarkResult, searchType: SearchTypes }[]> {
await this.setupDB();
const types = Utils.enumToArray(SearchTypes).map(a => a.key).concat([null]);
const results: { result: BenchmarkResult, searchType: SearchTypes }[] = [];
for (let i = 0; i < types.length; i++) {
2020-12-31 19:35:28 +08:00
const req = Utils.clone(this.requestTemplate);
req.params.text = text;
req.query[QueryParams.gallery.search.type] = types[i];
const bm = new Benchmark('Searching for `' + text + '` as `' + (types[i] ? SearchTypes[types[i]] : 'any') + '`', req);
BMGalleryRouter.addSearch(bm.BmExpressApp);
2020-12-31 04:13:19 +08:00
results.push({result: await bm.run(this.RUNS), searchType: types[i]});
}
return results;
}
async bmInstantSearch(text: string): Promise<BenchmarkResult> {
await this.setupDB();
2020-12-31 19:35:28 +08:00
const req = Utils.clone(this.requestTemplate);
req.params.text = text;
const bm = new Benchmark('Instant search for `' + text + '`', req);
BMGalleryRouter.addInstantSearch(bm.BmExpressApp);
2020-12-31 04:13:19 +08:00
return await bm.run(this.RUNS);
}
async bmAutocomplete(text: string): Promise<BenchmarkResult> {
await this.setupDB();
2020-12-31 19:35:28 +08:00
const req = Utils.clone(this.requestTemplate);
req.params.text = text;
const bm = new Benchmark('Auto complete for `' + text + '`', req);
BMGalleryRouter.addAutoComplete(bm.BmExpressApp);
2020-12-31 04:13:19 +08:00
return await bm.run(this.RUNS);
}
2020-12-31 04:54:07 +08:00
async getStatistic() {
await this.setupDB();
const gm = new GalleryManager();
const pm = new PersonManager();
2020-12-31 19:35:28 +08:00
2020-12-31 04:54:07 +08:00
return 'directories: ' + await gm.countDirectories() +
', photos: ' + await gm.countPhotos() +
', videos: ' + await gm.countVideos() +
2020-12-31 19:35:28 +08:00
', diskUsage : ' + Utils.renderDataSize(await gm.countMediaSize()) +
2020-12-31 04:54:07 +08:00
', persons : ' + await pm.countFaces() +
', unique persons (faces): ' + (await pm.getAll()).length;
}
private async init() {
if (this.inited === false) {
await this.setupDB();
const gm = new GalleryManager();
let biggest = 0;
let biggestPath = '/';
const queue = ['/'];
while (queue.length > 0) {
const dirPath = queue.shift();
const dir = await gm.listDirectory(dirPath);
dir.directories.forEach(d => queue.push(path.join(d.path + d.name)));
if (biggest < dir.media.length) {
biggestPath = path.join(dir.path + dir.name);
biggest = dir.media.length;
}
}
2020-12-31 19:35:28 +08:00
this.biggestDirPath = biggestPath;
console.log('updating path of biggest dir to: ' + this.biggestDirPath);
2020-12-31 04:54:07 +08:00
this.inited = true;
}
2020-12-31 19:35:28 +08:00
return this.biggestDirPath;
2020-12-31 04:54:07 +08:00
}
2020-12-31 04:13:19 +08:00
private resetDB = async () => {
Config.Server.Threading.enabled = false;
await ObjectManagers.reset();
2021-01-04 17:32:19 +08:00
await fs.promises.rmdir(ProjectPath.DBFolder, {recursive: true});
2020-12-31 04:13:19 +08:00
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
Config.Server.Jobs.scheduled = [];
await ObjectManagers.InitSQLManagers();
};
2021-01-04 17:32:19 +08:00
private async setupDB(): Promise<void> {
2020-12-31 04:13:19 +08:00
Config.Server.Threading.enabled = false;
2021-01-04 17:32:19 +08:00
await this.resetDB();
await new Promise<void>((resolve, reject) => {
2020-12-31 04:13:19 +08:00
try {
const indexingJob = new IndexingJob();
indexingJob.JobListener = {
onJobFinished: (job: IJob<any>, state: JobProgressStates, soloRun: boolean) => {
resolve();
},
onProgressUpdate: (progress: JobProgress) => {
}
};
indexingJob.start().catch(console.error);
} catch (e) {
console.error(e);
reject(e);
}
});
}
}