You've already forked pigallery2
mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-11-25 22:32:52 +02:00
improving benchmark
This commit is contained in:
39
benchmark/BMConfig.ts
Normal file
39
benchmark/BMConfig.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/* tslint:disable:no-inferrable-types */
|
||||||
|
import * as path from 'path';
|
||||||
|
import {ConfigClass, ConfigClassBuilder} from 'typeconfig/node';
|
||||||
|
import {ConfigProperty} from 'typeconfig/common';
|
||||||
|
|
||||||
|
|
||||||
|
@ConfigClass({
|
||||||
|
configPath: path.join(__dirname, './../bm_config.json'),
|
||||||
|
saveIfNotExist: true,
|
||||||
|
attachDescription: true,
|
||||||
|
enumsAsString: true,
|
||||||
|
softReadonly: true,
|
||||||
|
cli: {
|
||||||
|
enable: {
|
||||||
|
configPath: true,
|
||||||
|
attachState: true,
|
||||||
|
attachDescription: true,
|
||||||
|
rewriteCLIConfig: true,
|
||||||
|
rewriteENVConfig: true,
|
||||||
|
enumsAsString: true,
|
||||||
|
saveIfNotExist: true,
|
||||||
|
exitOnConfig: true
|
||||||
|
},
|
||||||
|
defaults: {
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export class PrivateConfigClass {
|
||||||
|
@ConfigProperty({description: 'Images are loaded from this folder (read permission required)'})
|
||||||
|
path: string = 'demo/images';
|
||||||
|
@ConfigProperty({description: 'Describe your system setup'})
|
||||||
|
system: string = '';
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const BMConfig = ConfigClassBuilder.attachInterface(new PrivateConfigClass());
|
||||||
|
BMConfig.loadSync();
|
||||||
@@ -11,6 +11,9 @@ import {Utils} from '../src/common/Utils';
|
|||||||
import {GalleryManager} from '../src/backend/model/database/sql/GalleryManager';
|
import {GalleryManager} from '../src/backend/model/database/sql/GalleryManager';
|
||||||
import {DirectoryDTO} from '../src/common/entities/DirectoryDTO';
|
import {DirectoryDTO} from '../src/common/entities/DirectoryDTO';
|
||||||
import {ServerConfig} from '../src/common/config/private/PrivateConfig';
|
import {ServerConfig} from '../src/common/config/private/PrivateConfig';
|
||||||
|
import {ProjectPath} from '../src/backend/ProjectPath';
|
||||||
|
import {PersonMWs} from '../src/backend/middlewares/PersonMWs';
|
||||||
|
import {ThumbnailGeneratorMWs} from '../src/backend/middlewares/thumbnail/ThumbnailGeneratorMWs';
|
||||||
|
|
||||||
const rimrafPR = util.promisify(rimraf);
|
const rimrafPR = util.promisify(rimraf);
|
||||||
|
|
||||||
@@ -30,7 +33,7 @@ export class BMIndexingManager extends IndexingManager {
|
|||||||
|
|
||||||
export class Benchmarks {
|
export class Benchmarks {
|
||||||
|
|
||||||
constructor(public RUNS: number, public dbFolder: string) {
|
constructor(public RUNS: number) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +55,20 @@ export class Benchmarks {
|
|||||||
return await this.benchmark(() => gm.listDirectory('./'));
|
return await this.benchmark(() => gm.listDirectory('./'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async bmListPersons(): Promise<BenchmarkResult> {
|
||||||
|
await this.setupDB();
|
||||||
|
Config.Server.Indexing.reIndexingSensitivity = ServerConfig.ReIndexingSensitivity.low;
|
||||||
|
return await this.benchmark(async () => {
|
||||||
|
await ObjectManagers.reset();
|
||||||
|
const req = {resultPipe: <any>null};
|
||||||
|
await this.nextToPromise(PersonMWs.listPersons, req, null);
|
||||||
|
await this.nextToPromise(PersonMWs.addSamplePhotoForAll, req, null);
|
||||||
|
await this.nextToPromise(ThumbnailGeneratorMWs.addThumbnailInfoForPersons, req, null);
|
||||||
|
await this.nextToPromise(PersonMWs.removeSamplePhotoForAll, req, null);
|
||||||
|
return req.resultPipe;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async bmAllSearch(text: string): Promise<{ result: BenchmarkResult, searchType: SearchTypes }[]> {
|
async bmAllSearch(text: string): Promise<{ result: BenchmarkResult, searchType: SearchTypes }[]> {
|
||||||
await this.setupDB();
|
await this.setupDB();
|
||||||
const types = Utils.enumToArray(SearchTypes).map(a => a.key).concat([null]);
|
const types = Utils.enumToArray(SearchTypes).map(a => a.key).concat([null]);
|
||||||
@@ -75,6 +92,16 @@ export class Benchmarks {
|
|||||||
return await this.benchmark(() => sm.autocomplete(text));
|
return await this.benchmark(() => sm.autocomplete(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private nextToPromise(fn: (req: any, res: any, next: Function) => void, request: any, response: any) {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
fn(request, resolve, (err?: any) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async benchmark(fn: () => Promise<{ media: any[], directories: any[] } | any[] | void>,
|
private async benchmark(fn: () => Promise<{ media: any[], directories: any[] } | any[] | void>,
|
||||||
beforeEach: () => Promise<any> = null,
|
beforeEach: () => Promise<any> = null,
|
||||||
@@ -122,9 +149,8 @@ export class Benchmarks {
|
|||||||
|
|
||||||
private resetDB = async () => {
|
private resetDB = async () => {
|
||||||
await SQLConnection.close();
|
await SQLConnection.close();
|
||||||
await rimrafPR(this.dbFolder);
|
await rimrafPR(ProjectPath.DBFolder);
|
||||||
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
||||||
Config.Server.Database.dbFolder = this.dbFolder;
|
|
||||||
await ObjectManagers.InitSQLManagers();
|
await ObjectManagers.InitSQLManagers();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import {BenchmarkResult, Benchmarks} from './Benchmarks';
|
|||||||
import {SearchTypes} from '../src/common/entities/AutoCompleteItem';
|
import {SearchTypes} from '../src/common/entities/AutoCompleteItem';
|
||||||
import {Utils} from '../src/common/Utils';
|
import {Utils} from '../src/common/Utils';
|
||||||
import {DiskMangerWorker} from '../src/backend/model/threading/DiskMangerWorker';
|
import {DiskMangerWorker} from '../src/backend/model/threading/DiskMangerWorker';
|
||||||
|
import {BMConfig} from './BMConfig';
|
||||||
|
import {GalleryManager} from '../src/backend/model/database/sql/GalleryManager';
|
||||||
|
|
||||||
const config: { path: string, system: string } = require(path.join(__dirname, 'config.json'));
|
|
||||||
Config.Server.Media.folder = config.path;
|
Config.Server.Media.folder = BMConfig.path;
|
||||||
const dbFolder = __dirname;
|
const dbFolder = path.join(__dirname, './../');
|
||||||
ProjectPath.reset();
|
ProjectPath.reset();
|
||||||
const RUNS = 50;
|
const RUNS = 50;
|
||||||
|
|
||||||
@@ -23,8 +25,9 @@ const printHeader = async () => {
|
|||||||
', ' + Utils.zeroPrefix(dt.getDate(), 2) +
|
', ' + Utils.zeroPrefix(dt.getDate(), 2) +
|
||||||
'.' + Utils.zeroPrefix(dt.getMonth() + 1, 2) +
|
'.' + Utils.zeroPrefix(dt.getMonth() + 1, 2) +
|
||||||
'.' + dt.getFullYear());
|
'.' + dt.getFullYear());
|
||||||
printLine('**System**: ' + config.system);
|
printLine('**System**: ' + BMConfig.system);
|
||||||
const dir = await DiskMangerWorker.scanDirectory('./');
|
const dir = await DiskMangerWorker.scanDirectory('./');
|
||||||
|
const gm = new GalleryManager();
|
||||||
printLine('**Gallery**: directories: ' +
|
printLine('**Gallery**: directories: ' +
|
||||||
dir.directories.length +
|
dir.directories.length +
|
||||||
' media: ' + dir.media.length +
|
' media: ' + dir.media.length +
|
||||||
@@ -52,7 +55,7 @@ const printResult = (result: BenchmarkResult, action: string, actionDetails: str
|
|||||||
|
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
const bm = new Benchmarks(RUNS, dbFolder);
|
const bm = new Benchmarks(RUNS);
|
||||||
|
|
||||||
// header
|
// header
|
||||||
await printHeader();
|
await printHeader();
|
||||||
@@ -60,6 +63,7 @@ const run = async () => {
|
|||||||
printResult(await bm.bmScanDirectory(), 'Scanning directory');
|
printResult(await bm.bmScanDirectory(), 'Scanning directory');
|
||||||
printResult(await bm.bmSaveDirectory(), 'Saving directory');
|
printResult(await bm.bmSaveDirectory(), 'Saving directory');
|
||||||
printResult(await bm.bmListDirectory(), 'Listing Directory');
|
printResult(await bm.bmListDirectory(), 'Listing Directory');
|
||||||
|
printResult(await bm.bmListPersons(), 'Listing Faces');
|
||||||
(await bm.bmAllSearch('a')).forEach(res => {
|
(await bm.bmAllSearch('a')).forEach(res => {
|
||||||
if (res.searchType !== null) {
|
if (res.searchType !== null) {
|
||||||
printResult(res.result, 'searching', '`a` as `' + SearchTypes[res.searchType] + '`');
|
printResult(res.result, 'searching', '`a` as `' + SearchTypes[res.searchType] + '`');
|
||||||
|
|||||||
@@ -146,7 +146,7 @@
|
|||||||
"@ffprobe-installer/ffprobe": "1.1.0",
|
"@ffprobe-installer/ffprobe": "1.1.0",
|
||||||
"bcrypt": "5.0.0",
|
"bcrypt": "5.0.0",
|
||||||
"mysql": "2.18.1",
|
"mysql": "2.18.1",
|
||||||
"sharp": "0.27.0"
|
"sharp": "0.23.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.17 <15.0"
|
"node": ">=10.17 <15.0"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ProjectPathClass {
|
|||||||
public TranscodedFolder: string;
|
public TranscodedFolder: string;
|
||||||
public FacesFolder: string;
|
public FacesFolder: string;
|
||||||
public FrontendFolder: string;
|
public FrontendFolder: string;
|
||||||
|
public DBFolder: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.reset();
|
this.reset();
|
||||||
@@ -33,6 +34,7 @@ class ProjectPathClass {
|
|||||||
this.TempFolder = this.getAbsolutePath(Config.Server.Media.tempFolder);
|
this.TempFolder = this.getAbsolutePath(Config.Server.Media.tempFolder);
|
||||||
this.TranscodedFolder = path.join(this.TempFolder, 'tc');
|
this.TranscodedFolder = path.join(this.TempFolder, 'tc');
|
||||||
this.FacesFolder = path.join(this.TempFolder, 'f');
|
this.FacesFolder = path.join(this.TempFolder, 'f');
|
||||||
|
this.DBFolder = this.getAbsolutePath(Config.Server.Database.dbFolder);
|
||||||
|
|
||||||
// create thumbnail folder if not exist
|
// create thumbnail folder if not exist
|
||||||
if (!fs.existsSync(this.TempFolder)) {
|
if (!fs.existsSync(this.TempFolder)) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export class UserManager implements IUserManager {
|
|||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.dbPath = path.join(ProjectPath.getAbsolutePath(Config.Server.Database.dbFolder), 'users.db');
|
this.dbPath = path.join(ProjectPath.DBFolder, 'users.db');
|
||||||
if (fs.existsSync(this.dbPath)) {
|
if (fs.existsSync(this.dbPath)) {
|
||||||
this.loadDB();
|
this.loadDB();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ export class SQLConnection {
|
|||||||
} else if (config.type === ServerConfig.DatabaseType.sqlite) {
|
} else if (config.type === ServerConfig.DatabaseType.sqlite) {
|
||||||
driver = {
|
driver = {
|
||||||
type: 'sqlite',
|
type: 'sqlite',
|
||||||
database: path.join(ProjectPath.getAbsolutePath(config.dbFolder), 'sqlite.db')
|
database: path.join(ProjectPath.getAbsolutePath(config.dbFolder), config.sqlite.DBFileName)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return driver;
|
return driver;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export class JobProgressManager {
|
|||||||
private timer: NodeJS.Timeout = null;
|
private timer: NodeJS.Timeout = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.dbPath = path.join(ProjectPath.getAbsolutePath(Config.Server.Database.dbFolder), 'jobs.db');
|
this.dbPath = path.join(ProjectPath.DBFolder, 'jobs.db');
|
||||||
this.loadDB().catch(console.error);
|
this.loadDB().catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,13 @@ export module ServerConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SubConfigClass()
|
||||||
|
export class SQLiteConfig {
|
||||||
|
@ConfigProperty()
|
||||||
|
DBFileName: string = 'sqlite.db';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SubConfigClass()
|
@SubConfigClass()
|
||||||
export class DataBaseConfig {
|
export class DataBaseConfig {
|
||||||
@ConfigProperty<DatabaseType, IPrivateConfig>({
|
@ConfigProperty<DatabaseType, IPrivateConfig>({
|
||||||
@@ -69,6 +76,9 @@ export module ServerConfig {
|
|||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
dbFolder: string = 'db';
|
dbFolder: string = 'db';
|
||||||
|
|
||||||
|
@ConfigProperty()
|
||||||
|
sqlite?: SQLiteConfig = new SQLiteConfig();
|
||||||
|
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
mysql?: MySQLConfig = new MySQLConfig();
|
mysql?: MySQLConfig = new MySQLConfig();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import * as util from 'util';
|
|||||||
import * as rimraf from 'rimraf';
|
import * as rimraf from 'rimraf';
|
||||||
import {SQLConnection} from '../../src/backend/model/database/sql/SQLConnection';
|
import {SQLConnection} from '../../src/backend/model/database/sql/SQLConnection';
|
||||||
import {ServerConfig} from '../../src/common/config/private/PrivateConfig';
|
import {ServerConfig} from '../../src/common/config/private/PrivateConfig';
|
||||||
|
import {ProjectPath} from '../../src/backend/ProjectPath';
|
||||||
|
|
||||||
declare let describe: any;
|
declare let describe: any;
|
||||||
const savedDescribe = describe;
|
const savedDescribe = describe;
|
||||||
@@ -63,6 +64,7 @@ export class SQLTestHelper {
|
|||||||
|
|
||||||
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
||||||
Config.Server.Database.dbFolder = this.tempDir;
|
Config.Server.Database.dbFolder = this.tempDir;
|
||||||
|
ProjectPath.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async initMySQL() {
|
private async initMySQL() {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
import {MediaDimensionEntity} from '../../../../../src/backend/model/database/sql/enitites/MediaEntity';
|
import {MediaDimensionEntity} from '../../../../../src/backend/model/database/sql/enitites/MediaEntity';
|
||||||
import {VersionEntity} from '../../../../../src/backend/model/database/sql/enitites/VersionEntity';
|
import {VersionEntity} from '../../../../../src/backend/model/database/sql/enitites/VersionEntity';
|
||||||
import {ServerConfig} from '../../../../../src/common/config/private/PrivateConfig';
|
import {ServerConfig} from '../../../../../src/common/config/private/PrivateConfig';
|
||||||
|
import {ProjectPath} from '../../../../../src/backend/ProjectPath';
|
||||||
|
|
||||||
|
|
||||||
const rimrafPR = util.promisify(rimraf);
|
const rimrafPR = util.promisify(rimraf);
|
||||||
@@ -31,6 +32,7 @@ describe('Typeorm integration', () => {
|
|||||||
|
|
||||||
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
||||||
Config.Server.Database.dbFolder = tempDir;
|
Config.Server.Database.dbFolder = tempDir;
|
||||||
|
ProjectPath.reset();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ describe('GalleryRouter', () => {
|
|||||||
Config.Server.Database.dbFolder = tempDir;
|
Config.Server.Database.dbFolder = tempDir;
|
||||||
ProjectPath.ImageFolder = path.join(__dirname, '../../assets');
|
ProjectPath.ImageFolder = path.join(__dirname, '../../assets');
|
||||||
ProjectPath.TempFolder = tempDir;
|
ProjectPath.TempFolder = tempDir;
|
||||||
|
ProjectPath.reset();
|
||||||
|
|
||||||
server = new Server();
|
server = new Server();
|
||||||
await server.onStarted.wait();
|
await server.onStarted.wait();
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {SuperAgentStatic} from 'superagent';
|
|||||||
import {RouteTestingHelper} from './RouteTestingHelper';
|
import {RouteTestingHelper} from './RouteTestingHelper';
|
||||||
import {ErrorCodes} from '../../../../src/common/entities/Error';
|
import {ErrorCodes} from '../../../../src/common/entities/Error';
|
||||||
import {ServerConfig} from '../../../../src/common/config/private/PrivateConfig';
|
import {ServerConfig} from '../../../../src/common/config/private/PrivateConfig';
|
||||||
|
import {ProjectPath} from '../../../../src/backend/ProjectPath';
|
||||||
|
|
||||||
|
|
||||||
process.env.NODE_ENV = 'test';
|
process.env.NODE_ENV = 'test';
|
||||||
@@ -39,6 +40,7 @@ describe('UserRouter', () => {
|
|||||||
Config.Server.Threading.enabled = false;
|
Config.Server.Threading.enabled = false;
|
||||||
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
||||||
Config.Server.Database.dbFolder = tempDir;
|
Config.Server.Database.dbFolder = tempDir;
|
||||||
|
ProjectPath.reset();
|
||||||
|
|
||||||
|
|
||||||
server = new Server();
|
server = new Server();
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {Config} from '../../../../../src/common/config/private/Config';
|
|||||||
import {SQLConnection} from '../../../../../src/backend/model/database/sql/SQLConnection';
|
import {SQLConnection} from '../../../../../src/backend/model/database/sql/SQLConnection';
|
||||||
import {Server} from '../../../../../src/backend/server';
|
import {Server} from '../../../../../src/backend/server';
|
||||||
import {ServerConfig} from '../../../../../src/common/config/private/PrivateConfig';
|
import {ServerConfig} from '../../../../../src/common/config/private/PrivateConfig';
|
||||||
|
import {ProjectPath} from '../../../../../src/backend/ProjectPath';
|
||||||
|
|
||||||
process.env.NODE_ENV = 'test';
|
process.env.NODE_ENV = 'test';
|
||||||
const chai: any = require('chai');
|
const chai: any = require('chai');
|
||||||
@@ -21,6 +22,7 @@ describe('SettingsRouter', () => {
|
|||||||
Config.Server.Threading.enabled = false;
|
Config.Server.Threading.enabled = false;
|
||||||
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
Config.Server.Database.type = ServerConfig.DatabaseType.sqlite;
|
||||||
Config.Server.Database.dbFolder = tempDir;
|
Config.Server.Database.dbFolder = tempDir;
|
||||||
|
ProjectPath.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user