Processes get cleaned up when process quits
This commit is contained in:
parent
5b03182b3d
commit
acd7e3bae2
|
@ -62,5 +62,6 @@ export declare class FD {
|
||||||
stop(image: string): Promise<fdResult>;
|
stop(image: string): Promise<fdResult>;
|
||||||
isConnected(): boolean;
|
isConnected(): boolean;
|
||||||
private test;
|
private test;
|
||||||
|
exit(): Promise<void>;
|
||||||
}
|
}
|
||||||
export type { Action, Mode, fdOutgoingPosition, fdOutgoingMessage, fdIncomingMessage, fdResult };
|
export type { Action, Mode, fdOutgoingPosition, fdOutgoingMessage, fdIncomingMessage, fdResult };
|
||||||
|
|
|
@ -26,6 +26,8 @@ var Mode;
|
||||||
})(Mode || (Mode = {}));
|
})(Mode || (Mode = {}));
|
||||||
class FD {
|
class FD {
|
||||||
constructor(bin, width, height, host, port, mock = false) {
|
constructor(bin, width, height, host, port, mock = false) {
|
||||||
|
this.shell = null;
|
||||||
|
this.client = null;
|
||||||
this.socketAvailable = false;
|
this.socketAvailable = false;
|
||||||
this.socketConnected = false;
|
this.socketConnected = false;
|
||||||
this.waiting = null;
|
this.waiting = null;
|
||||||
|
@ -104,7 +106,7 @@ class FD {
|
||||||
send(msg) {
|
send(msg) {
|
||||||
const json = JSON.stringify(msg);
|
const json = JSON.stringify(msg);
|
||||||
this.log.info(json);
|
this.log.info(json);
|
||||||
if (!this.mock)
|
if (!this.mock && this.client !== null)
|
||||||
this.client.write(json);
|
this.client.write(json);
|
||||||
}
|
}
|
||||||
receive(json) {
|
receive(json) {
|
||||||
|
@ -243,6 +245,12 @@ class FD {
|
||||||
this.log.warn('QUITTING!!!!');
|
this.log.warn('QUITTING!!!!');
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
|
async exit() {
|
||||||
|
if (this.client !== null)
|
||||||
|
this.client.end();
|
||||||
|
if (this.shell !== null)
|
||||||
|
this.shell.kill();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.FD = FD;
|
exports.FD = FD;
|
||||||
module.exports = { FD };
|
module.exports = { FD };
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -17,7 +17,8 @@ const imageExtensions = [
|
||||||
'.png',
|
'.png',
|
||||||
'.tif',
|
'.tif',
|
||||||
'.tiff',
|
'.tiff',
|
||||||
'.bmp'
|
'.bmp',
|
||||||
|
'.dpx'
|
||||||
];
|
];
|
||||||
class Files {
|
class Files {
|
||||||
static async init(sequencesDir) {
|
static async init(sequencesDir) {
|
||||||
|
@ -106,7 +107,6 @@ class Files {
|
||||||
if (!await this.isSequence(dirPath)) {
|
if (!await this.isSequence(dirPath)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
console.log(`Adding ${dirPath}`);
|
|
||||||
dirs.push({
|
dirs.push({
|
||||||
created: +stats.birthtime,
|
created: +stats.birthtime,
|
||||||
path: dirPath,
|
path: dirPath,
|
||||||
|
@ -131,7 +131,6 @@ class Files {
|
||||||
catch (err) {
|
catch (err) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
console.dir(`${dirPath} ${all.length}`);
|
|
||||||
for (let elem of all) {
|
for (let elem of all) {
|
||||||
filePath = (0, path_1.join)(dirPath, elem);
|
filePath = (0, path_1.join)(dirPath, elem);
|
||||||
try {
|
try {
|
||||||
|
@ -141,7 +140,6 @@ class Files {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
if (stats.isFile() && elem.substring(0, 1) !== '.' && imageExtensions.indexOf((0, path_1.extname)((0, path_1.basename)(elem).toLowerCase())) !== -1) {
|
if (stats.isFile() && elem.substring(0, 1) !== '.' && imageExtensions.indexOf((0, path_1.extname)((0, path_1.basename)(elem).toLowerCase())) !== -1) {
|
||||||
console.log(`Has file ${filePath}`);
|
|
||||||
sequence = true;
|
sequence = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,14 @@
|
||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
export declare class Image {
|
export declare class Image {
|
||||||
|
private prefix;
|
||||||
private thumbnailCache;
|
private thumbnailCache;
|
||||||
private thumbnailHash;
|
private thumbnailHash;
|
||||||
private blankCache;
|
private blankCache;
|
||||||
private blankHash;
|
private blankHash;
|
||||||
|
private tmp;
|
||||||
constructor();
|
constructor();
|
||||||
|
private mktemp;
|
||||||
|
private dpx2png;
|
||||||
thumbnail(path: string, width: number, height: number): Promise<Buffer>;
|
thumbnail(path: string, width: number, height: number): Promise<Buffer>;
|
||||||
blank(width: number, height: number): Promise<Buffer>;
|
blank(width: number, height: number): Promise<Buffer>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,16 +6,64 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.Image = void 0;
|
exports.Image = void 0;
|
||||||
const sharp_1 = __importDefault(require("sharp"));
|
const sharp_1 = __importDefault(require("sharp"));
|
||||||
const hash_1 = require("../hash");
|
const hash_1 = require("../hash");
|
||||||
|
const path_1 = require("path");
|
||||||
|
const os_1 = require("os");
|
||||||
|
const promises_1 = require("fs/promises");
|
||||||
|
const shell_1 = require("../shell");
|
||||||
class Image {
|
class Image {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.prefix = 'fm_thumbs';
|
||||||
this.thumbnailCache = null;
|
this.thumbnailCache = null;
|
||||||
this.thumbnailHash = null;
|
this.thumbnailHash = null;
|
||||||
this.blankCache = null;
|
this.blankCache = null;
|
||||||
this.blankHash = null;
|
this.blankHash = null;
|
||||||
|
this.tmp = null;
|
||||||
|
if (this.tmp === null) {
|
||||||
|
this.tmp = (0, os_1.tmpdir)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async mktemp(ext = '.png') {
|
||||||
|
const randomString = Math.random().toString(36).slice(2);
|
||||||
|
const tempPath = (0, path_1.join)(this.tmp, this.prefix, randomString + `.${ext}`);
|
||||||
|
try {
|
||||||
|
await (0, promises_1.mkdir)((0, path_1.join)(this.tmp, this.prefix));
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
return tempPath;
|
||||||
|
}
|
||||||
|
async dpx2png(input, output) {
|
||||||
|
let dpx = null;
|
||||||
|
const args = [
|
||||||
|
'convert',
|
||||||
|
input,
|
||||||
|
'-colorspace', 'RGB',
|
||||||
|
'-depth', '8',
|
||||||
|
output
|
||||||
|
];
|
||||||
|
const shell = new shell_1.Shell(args, null, null, null, true);
|
||||||
|
try {
|
||||||
|
await shell.execute();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async thumbnail(path, width, height) {
|
async thumbnail(path, width, height) {
|
||||||
const hash = hash_1.Hashes.stringHash(`${path},${width},${height}`);
|
const hash = hash_1.Hashes.stringHash(`${path},${width},${height}`);
|
||||||
|
let newPath = null;
|
||||||
if (hash !== this.thumbnailHash) {
|
if (hash !== this.thumbnailHash) {
|
||||||
|
if ((0, path_1.extname)(path).toLowerCase() === '.dpx') {
|
||||||
|
try {
|
||||||
|
newPath = await this.mktemp('png');
|
||||||
|
await this.dpx2png(path, newPath);
|
||||||
|
path = newPath;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
const options = {
|
const options = {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
@ -23,6 +71,14 @@ class Image {
|
||||||
};
|
};
|
||||||
this.thumbnailCache = await (0, sharp_1.default)(path).resize(options).jpeg().toBuffer();
|
this.thumbnailCache = await (0, sharp_1.default)(path).resize(options).jpeg().toBuffer();
|
||||||
this.thumbnailHash = hash;
|
this.thumbnailHash = hash;
|
||||||
|
if (newPath !== null) {
|
||||||
|
try {
|
||||||
|
await (0, promises_1.unlink)(newPath);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this.thumbnailCache;
|
return this.thumbnailCache;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/image/index.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,kCAAiC;AAEjC,MAAa,KAAK;IAKjB;QAJQ,mBAAc,GAAY,IAAI,CAAC;QAC/B,kBAAa,GAAY,IAAI,CAAC;QAC9B,eAAU,GAAY,IAAI,CAAC;QAC3B,cAAS,GAAY,IAAI,CAAC;IAGlC,CAAC;IACM,KAAK,CAAC,SAAS,CAAE,IAAa,EAAE,KAAc,EAAE,MAAc;QACpE,MAAM,IAAI,GAAY,aAAM,CAAC,UAAU,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC;QACtE,IAAI,IAAI,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;YACjC,MAAM,OAAO,GAAmB;gBAC/B,KAAK;gBACL,MAAM;gBACN,GAAG,EAAE,eAAK,CAAC,GAAG,CAAC,IAAI;aACnB,CAAA;YACD,IAAI,CAAC,cAAc,GAAG,MAAM,IAAA,eAAK,EAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YAC1E,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC;IAC5B,CAAC;IAEM,KAAK,CAAC,KAAK,CAAE,KAAc,EAAE,MAAe;QAClD,MAAM,IAAI,GAAY,aAAM,CAAC,UAAU,CAAC,GAAG,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC;QAC9D,IAAI,IAAI,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAkB;gBAC9B,MAAM,EAAE;oBACP,KAAK;oBACL,MAAM;oBACN,QAAQ,EAAE,CAAC;oBACX,UAAU,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;iBACtC;aACD,CAAC;YACF,IAAI,CAAC,UAAU,GAAG,MAAM,IAAA,eAAK,EAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YACzD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;CACD;AAtCD,sBAsCC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC"}
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/image/index.ts"],"names":[],"mappings":"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"}
|
|
@ -480,4 +480,28 @@ async function main() {
|
||||||
setInterval(keepAlive, 30000);
|
setInterval(keepAlive, 30000);
|
||||||
}
|
}
|
||||||
main();
|
main();
|
||||||
|
process.stdin.resume(); // so the program will not close instantly
|
||||||
|
async function exitHandler(options, exitCode) {
|
||||||
|
if (options.cleanup) {
|
||||||
|
log.info(`Cleaning up...`);
|
||||||
|
try {
|
||||||
|
await fd.exit();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
log.error('Error cleanly exiting filmout_display (fd) executable', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exitCode == 'SIGINT' ? log.info(`exit: ${exitCode}`) : log.error(`exit: ${exitCode}`, new Error(`Exited with non-zero code: "${exitCode}"`));
|
||||||
|
if (options.exit)
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
// do something when app is closing
|
||||||
|
process.on('exit', exitHandler.bind(null, { cleanup: true }));
|
||||||
|
// catches ctrl+c event
|
||||||
|
process.on('SIGINT', exitHandler.bind(null, { exit: true }));
|
||||||
|
// catches "kill pid" (for example: nodemon restart)
|
||||||
|
process.on('SIGUSR1', exitHandler.bind(null, { exit: true }));
|
||||||
|
process.on('SIGUSR2', exitHandler.bind(null, { exit: true }));
|
||||||
|
// catches uncaught exceptions
|
||||||
|
process.on('uncaughtException', exitHandler.bind(null, { exit: true }));
|
||||||
//# sourceMappingURL=index.js.map
|
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -56,9 +56,9 @@ export class FD {
|
||||||
private height : number;
|
private height : number;
|
||||||
private host : string;
|
private host : string;
|
||||||
private port : number;
|
private port : number;
|
||||||
private shell : Shell;
|
private shell : Shell = null;
|
||||||
private log : Logger;
|
private log : Logger;
|
||||||
private client : Socket;
|
private client : Socket = null;
|
||||||
private socketAvailable : boolean = false;
|
private socketAvailable : boolean = false;
|
||||||
private socketConnected : boolean = false;
|
private socketConnected : boolean = false;
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ export class FD {
|
||||||
private send (msg : fdOutgoingMessage) {
|
private send (msg : fdOutgoingMessage) {
|
||||||
const json : string = JSON.stringify(msg);
|
const json : string = JSON.stringify(msg);
|
||||||
this.log.info(json);
|
this.log.info(json);
|
||||||
if (!this.mock) this.client.write(json);
|
if (!this.mock && this.client !== null) this.client.write(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
private receive (json : string) {
|
private receive (json : string) {
|
||||||
|
@ -292,6 +292,11 @@ export class FD {
|
||||||
this.log.warn('QUITTING!!!!');
|
this.log.warn('QUITTING!!!!');
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async exit () {
|
||||||
|
if (this.client !== null) this.client.end();
|
||||||
|
if (this.shell !== null) this.shell.kill();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { FD };
|
module.exports = { FD };
|
||||||
|
|
|
@ -37,7 +37,8 @@ const imageExtensions : string[] = [
|
||||||
'.png',
|
'.png',
|
||||||
'.tif',
|
'.tif',
|
||||||
'.tiff',
|
'.tiff',
|
||||||
'.bmp'
|
'.bmp',
|
||||||
|
'.dpx'
|
||||||
];
|
];
|
||||||
|
|
||||||
export class Files {
|
export class Files {
|
||||||
|
@ -152,7 +153,7 @@ export class Files {
|
||||||
let all : string[];
|
let all : string[];
|
||||||
let stats : Stats;
|
let stats : Stats;
|
||||||
let filePath : string;
|
let filePath : string;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
all = await readdir(dirPath);
|
all = await readdir(dirPath);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -1,18 +1,67 @@
|
||||||
import sharp from 'sharp';
|
import sharp from 'sharp';
|
||||||
import type { SharpOptions, ResizeOptions } from 'sharp';
|
import type { SharpOptions, ResizeOptions } from 'sharp';
|
||||||
import { Hashes } from '../hash';
|
import { Hashes } from '../hash';
|
||||||
|
import { join, extname } from 'path';
|
||||||
|
import { tmpdir } from 'os';
|
||||||
|
import { mkdir, unlink } from 'fs/promises';
|
||||||
|
import { Shell } from '../shell';
|
||||||
|
|
||||||
export class Image {
|
export class Image {
|
||||||
|
private prefix : string = 'fm_thumbs';
|
||||||
private thumbnailCache : Buffer = null;
|
private thumbnailCache : Buffer = null;
|
||||||
private thumbnailHash : string = null;
|
private thumbnailHash : string = null;
|
||||||
private blankCache : Buffer = null;
|
private blankCache : Buffer = null;
|
||||||
private blankHash : string = null;
|
private blankHash : string = null;
|
||||||
constructor () {
|
private tmp : string = null;
|
||||||
|
|
||||||
|
constructor () {
|
||||||
|
if (this.tmp === null) {
|
||||||
|
this.tmp = tmpdir();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async mktemp (ext : string = '.png') : Promise<string> {
|
||||||
|
const randomString : string = Math.random().toString(36).slice(2);
|
||||||
|
const tempPath : string = join(this.tmp, this.prefix, randomString + `.${ext}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await mkdir(join(this.tmp, this.prefix));
|
||||||
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
return tempPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async dpx2png (input : string, output : string) {
|
||||||
|
let dpx : any = null;
|
||||||
|
const args : string[] = [
|
||||||
|
'convert',
|
||||||
|
input,
|
||||||
|
'-colorspace', 'RGB',
|
||||||
|
'-depth', '8',
|
||||||
|
output
|
||||||
|
];
|
||||||
|
const shell : Shell = new Shell(args, null, null, null, true);
|
||||||
|
try {
|
||||||
|
await shell.execute();
|
||||||
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async thumbnail (path : string, width : number, height: number) : Promise<Buffer>{
|
public async thumbnail (path : string, width : number, height: number) : Promise<Buffer>{
|
||||||
const hash : string = Hashes.stringHash(`${path},${width},${height}`);
|
const hash : string = Hashes.stringHash(`${path},${width},${height}`);
|
||||||
|
let newPath : string = null;
|
||||||
if (hash !== this.thumbnailHash) {
|
if (hash !== this.thumbnailHash) {
|
||||||
|
if (extname(path).toLowerCase() === '.dpx') {
|
||||||
|
try {
|
||||||
|
newPath = await this.mktemp('png');
|
||||||
|
await this.dpx2png(path, newPath);
|
||||||
|
path = newPath;
|
||||||
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
const options : ResizeOptions = {
|
const options : ResizeOptions = {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
@ -20,6 +69,13 @@ export class Image {
|
||||||
}
|
}
|
||||||
this.thumbnailCache = await sharp(path).resize(options).jpeg().toBuffer();
|
this.thumbnailCache = await sharp(path).resize(options).jpeg().toBuffer();
|
||||||
this.thumbnailHash = hash;
|
this.thumbnailHash = hash;
|
||||||
|
if (newPath !== null) {
|
||||||
|
try {
|
||||||
|
await unlink(newPath);
|
||||||
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this.thumbnailCache;
|
return this.thumbnailCache;
|
||||||
}
|
}
|
||||||
|
|
30
src/index.ts
30
src/index.ts
|
@ -484,4 +484,32 @@ async function main () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
||||||
|
process.stdin.resume(); // so the program will not close instantly
|
||||||
|
|
||||||
|
async function exitHandler(options : any, exitCode : string) {
|
||||||
|
if (options.cleanup) {
|
||||||
|
log.info(`Cleaning up...`);
|
||||||
|
try {
|
||||||
|
await fd.exit();
|
||||||
|
} catch (err) {
|
||||||
|
log.error('Error cleanly exiting filmout_display (fd) executable', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exitCode == 'SIGINT' ? log.info(`exit: ${exitCode}`) : log.error(`exit: ${exitCode}`, new Error(`Exited with non-zero code: "${exitCode}"`));
|
||||||
|
if (options.exit) process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// do something when app is closing
|
||||||
|
process.on('exit', exitHandler.bind(null,{cleanup:true}));
|
||||||
|
|
||||||
|
// catches ctrl+c event
|
||||||
|
process.on('SIGINT', exitHandler.bind(null, {exit:true}));
|
||||||
|
|
||||||
|
// catches "kill pid" (for example: nodemon restart)
|
||||||
|
process.on('SIGUSR1', exitHandler.bind(null, {exit:true}));
|
||||||
|
process.on('SIGUSR2', exitHandler.bind(null, {exit:true}));
|
||||||
|
|
||||||
|
// catches uncaught exceptions
|
||||||
|
process.on('uncaughtException', exitHandler.bind(null, {exit:true}));
|
Loading…
Reference in New Issue