mirror of
https://github.com/immich-app/immich.git
synced 2024-11-20 18:15:52 +02:00
refactor(server): worker env (#13160)
This commit is contained in:
parent
892a35acb5
commit
db1623f43f
@ -1,3 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
node /usr/src/app/dist/utils/healthcheck.js
|
||||
node /usr/src/app/dist/bin/healthcheck.js
|
||||
|
@ -18,7 +18,6 @@
|
||||
"check": "tsc --noEmit",
|
||||
"check:code": "npm run format && npm run lint && npm run check",
|
||||
"check:all": "npm run check:code && npm run test:cov",
|
||||
"healthcheck": "node ./dist/utils/healthcheck.js",
|
||||
"test": "vitest",
|
||||
"test:watch": "vitest --watch",
|
||||
"test:cov": "vitest --coverage",
|
||||
|
@ -1,12 +1,14 @@
|
||||
#!/usr/bin/env node
|
||||
const port = Number(process.env.IMMICH_PORT) || 3001;
|
||||
const controller = new AbortController();
|
||||
import { ImmichWorker } from 'src/enum';
|
||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||
|
||||
const main = async () => {
|
||||
if (!process.env.IMMICH_WORKERS_INCLUDE?.includes('api')) {
|
||||
const { workers, port } = new ConfigRepository().getEnv();
|
||||
if (!workers.includes(ImmichWorker.API)) {
|
||||
process.exit();
|
||||
}
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 2000);
|
||||
try {
|
||||
const response = await fetch(`http://localhost:${port}/api/server-info/ping`, {
|
@ -334,3 +334,8 @@ export enum ImmichEnvironment {
|
||||
TESTING = 'testing',
|
||||
PRODUCTION = 'production',
|
||||
}
|
||||
|
||||
export enum ImmichWorker {
|
||||
API = 'api',
|
||||
MICROSERVICES = 'microservices',
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ImmichEnvironment, LogLevel } from 'src/enum';
|
||||
import { ImmichEnvironment, ImmichWorker, LogLevel } from 'src/enum';
|
||||
import { VectorExtension } from 'src/interfaces/database.interface';
|
||||
|
||||
export const IConfigRepository = 'IConfigRepository';
|
||||
@ -18,6 +18,8 @@ export interface EnvData {
|
||||
ignoreMountCheckErrors: boolean;
|
||||
};
|
||||
|
||||
workers: ImmichWorker[];
|
||||
|
||||
nodeVersion?: string;
|
||||
}
|
||||
|
||||
|
@ -2,20 +2,15 @@ import { CommandFactory } from 'nest-commander';
|
||||
import { fork } from 'node:child_process';
|
||||
import { Worker } from 'node:worker_threads';
|
||||
import { ImmichAdminModule } from 'src/app.module';
|
||||
import { LogLevel } from 'src/enum';
|
||||
import { getWorkers } from 'src/utils/workers';
|
||||
const immichApp = process.argv[2] || process.env.IMMICH_APP;
|
||||
import { ImmichWorker, LogLevel } from 'src/enum';
|
||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||
|
||||
if (process.argv[2] === immichApp) {
|
||||
const immichApp = process.argv[2];
|
||||
if (immichApp) {
|
||||
process.argv.splice(2, 1);
|
||||
}
|
||||
|
||||
async function bootstrapImmichAdmin() {
|
||||
process.env.IMMICH_LOG_LEVEL = LogLevel.WARN;
|
||||
await CommandFactory.run(ImmichAdminModule);
|
||||
}
|
||||
|
||||
function bootstrapWorker(name: string) {
|
||||
function bootstrapWorker(name: ImmichWorker) {
|
||||
console.log(`Starting ${name} worker`);
|
||||
|
||||
const execArgv = process.execArgv.map((arg) => (arg.startsWith('--inspect') ? '--inspect=0.0.0.0:9231' : arg));
|
||||
@ -35,26 +30,27 @@ function bootstrapWorker(name: string) {
|
||||
}
|
||||
|
||||
function bootstrap() {
|
||||
switch (immichApp) {
|
||||
case 'immich-admin': {
|
||||
process.title = 'immich_admin_cli';
|
||||
return bootstrapImmichAdmin();
|
||||
}
|
||||
case 'immich': {
|
||||
if (!process.env.IMMICH_WORKERS_INCLUDE) {
|
||||
process.env.IMMICH_WORKERS_INCLUDE = 'api';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'microservices': {
|
||||
if (!process.env.IMMICH_WORKERS_INCLUDE) {
|
||||
process.env.IMMICH_WORKERS_INCLUDE = 'microservices';
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (immichApp === 'immich-admin') {
|
||||
process.title = 'immich_admin_cli';
|
||||
process.env.IMMICH_LOG_LEVEL = LogLevel.WARN;
|
||||
return CommandFactory.run(ImmichAdminModule);
|
||||
}
|
||||
|
||||
if (immichApp === 'immich' || immichApp === 'microservices') {
|
||||
console.error(
|
||||
`Using "start.sh ${immichApp}" has been deprecated. See https://github.com/immich-app/immich/releases/tag/v1.118.0 for more information.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (immichApp) {
|
||||
console.error(`Unknown command: "${immichApp}"`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
process.title = 'immich';
|
||||
for (const worker of getWorkers()) {
|
||||
const { workers } = new ConfigRepository().getEnv();
|
||||
for (const worker of workers) {
|
||||
bootstrapWorker(worker);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { getWorkers } from 'src/utils/workers';
|
||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||
|
||||
const getWorkers = () => new ConfigRepository().getEnv().workers;
|
||||
|
||||
describe('getWorkers', () => {
|
||||
beforeEach(() => {
|
@ -1,13 +1,30 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { getVectorExtension } from 'src/database.config';
|
||||
import { ImmichEnvironment, LogLevel } from 'src/enum';
|
||||
import { ImmichEnvironment, ImmichWorker, LogLevel } from 'src/enum';
|
||||
import { EnvData, IConfigRepository } from 'src/interfaces/config.interface';
|
||||
import { setDifference } from 'src/utils/set';
|
||||
|
||||
// TODO replace src/config validation with class-validator, here
|
||||
|
||||
const WORKER_TYPES = new Set(Object.values(ImmichWorker));
|
||||
|
||||
const asSet = (value: string | undefined, defaults: ImmichWorker[]) => {
|
||||
const values = (value || '').replaceAll(/\s/g, '').split(',').filter(Boolean);
|
||||
return new Set(values.length === 0 ? defaults : (values as ImmichWorker[]));
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class ConfigRepository implements IConfigRepository {
|
||||
getEnv(): EnvData {
|
||||
const included = asSet(process.env.IMMICH_WORKERS_INCLUDE, [ImmichWorker.API, ImmichWorker.MICROSERVICES]);
|
||||
const excluded = asSet(process.env.IMMICH_WORKERS_EXCLUDE, []);
|
||||
const workers = [...setDifference(included, excluded)];
|
||||
for (const worker of workers) {
|
||||
if (!WORKER_TYPES.has(worker)) {
|
||||
throw new Error(`Invalid worker(s) found: ${workers.join(',')}`);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
port: Number(process.env.IMMICH_PORT) || 3001,
|
||||
environment: process.env.IMMICH_ENV as ImmichEnvironment,
|
||||
@ -20,6 +37,7 @@ export class ConfigRepository implements IConfigRepository {
|
||||
storage: {
|
||||
ignoreMountCheckErrors: process.env.IMMICH_IGNORE_MOUNT_CHECK_ERRORS === 'true',
|
||||
},
|
||||
workers,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
const WORKER_TYPES = new Set(['api', 'microservices']);
|
||||
|
||||
export const getWorkers = () => {
|
||||
let workers = ['api', 'microservices'];
|
||||
const includedWorkers = process.env.IMMICH_WORKERS_INCLUDE?.replaceAll(/\s/g, '');
|
||||
const excludedWorkers = process.env.IMMICH_WORKERS_EXCLUDE?.replaceAll(/\s/g, '');
|
||||
|
||||
if (includedWorkers) {
|
||||
workers = includedWorkers.split(',');
|
||||
}
|
||||
|
||||
if (excludedWorkers) {
|
||||
workers = workers.filter((worker) => !excludedWorkers.split(',').includes(worker));
|
||||
}
|
||||
|
||||
if (workers.some((worker) => !WORKER_TYPES.has(worker))) {
|
||||
throw new Error(`Invalid worker(s) found: ${workers}`);
|
||||
}
|
||||
|
||||
return workers;
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
import { ImmichEnvironment } from 'src/enum';
|
||||
import { ImmichEnvironment, ImmichWorker } from 'src/enum';
|
||||
import { EnvData, IConfigRepository } from 'src/interfaces/config.interface';
|
||||
import { DatabaseExtension } from 'src/interfaces/database.interface';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
@ -15,6 +15,8 @@ const envData: EnvData = {
|
||||
storage: {
|
||||
ignoreMountCheckErrors: false,
|
||||
},
|
||||
|
||||
workers: [ImmichWorker.API, ImmichWorker.MICROSERVICES],
|
||||
};
|
||||
|
||||
export const newConfigRepositoryMock = (): Mocked<IConfigRepository> => {
|
||||
|
Loading…
Reference in New Issue
Block a user