fix(striker-ui-api): use separate fifo for each server screenshot request and read all data chunks

main
Tsu-ba-me 3 years ago
parent 90c3004e90
commit 1d39e4d918
  1. 1
      striker-ui-api/src/lib/consts/SERVER_PATHS.ts
  2. 58
      striker-ui-api/src/lib/request_handlers/server/getServerDetail.ts

@ -10,6 +10,7 @@ const EMPTY_SERVER_PATHS: ServerPath = {
usr: { usr: {
bin: { bin: {
mkfifo: {}, mkfifo: {},
rm: {},
sed: {}, sed: {},
}, },
sbin: { sbin: {

@ -1,24 +1,27 @@
import assert from 'assert'; import assert from 'assert';
import { RequestHandler } from 'express'; import { RequestHandler } from 'express';
import { createReadStream, existsSync, rmSync, statSync } from 'fs'; import { createReadStream } from 'fs';
import path from 'path'; import path from 'path';
import { REP_UUID } from '../../consts/REG_EXP_PATTERNS'; import { REP_UUID } from '../../consts/REG_EXP_PATTERNS';
import SERVER_PATHS from '../../consts/SERVER_PATHS'; import SERVER_PATHS from '../../consts/SERVER_PATHS';
import { dbQuery, sub } from '../../accessModule'; import { dbQuery, sub } from '../../accessModule';
import { mkfifo } from '../../mkfifo';
import { sanitizeQS } from '../../sanitizeQS'; import { sanitizeQS } from '../../sanitizeQS';
import { mkfifo, rm } from '../../shell';
export const getServerDetail: RequestHandler = (request, response) => { export const getServerDetail: RequestHandler = (request, response) => {
const { serverUUID } = request.params; const { serverUUID } = request.params;
const { ss, resize } = request.query; const { ss, resize } = request.query;
const epoch = Date.now();
const isScreenshot = sanitizeQS(ss, { const isScreenshot = sanitizeQS(ss, {
returnType: 'boolean', returnType: 'boolean',
}); });
console.log(`serverUUID=[${serverUUID}],isScreenshot=[${isScreenshot}]`); console.log(
`serverUUID=[${serverUUID}],epoch=[${epoch}],isScreenshot=[${isScreenshot}]`,
);
try { try {
assert( assert(
@ -67,27 +70,47 @@ export const getServerDetail: RequestHandler = (request, response) => {
console.log(`serverHostUUID=[${serverHostUUID}]`); console.log(`serverHostUUID=[${serverHostUUID}]`);
const imageFileName = `${serverUUID}_screenshot`; const imageFileName = `${serverUUID}_screenshot_${epoch}`;
const imageFilePath = path.join(SERVER_PATHS.tmp.self, imageFileName); const imageFilePath = path.join(SERVER_PATHS.tmp.self, imageFileName);
try { try {
if (existsSync(imageFilePath)) { mkfifo(imageFilePath);
if (!statSync(imageFilePath).isFIFO()) {
rmSync(imageFilePath);
mkfifo(imageFilePath);
}
} else {
mkfifo(imageFilePath);
}
const namedPipeReadStream = createReadStream(imageFilePath, { const namedPipeReadStream = createReadStream(imageFilePath, {
autoClose: true,
encoding: 'utf-8', encoding: 'utf-8',
}); });
namedPipeReadStream.once('data', (data) => { let imageData = '';
response.status(200).send({ screenshot: data.toString().trim() });
namedPipeReadStream.once('close', () => {
console.log(`On close; removing named pipe at ${imageFilePath}.`);
try {
rm(imageFilePath);
} catch (cleanPipeError) {
console.log(
`Failed to clean up named pipe; CAUSE: ${cleanPipeError}`,
);
}
});
namedPipeReadStream.once('end', () => {
response.status(200).send({ screenshot: imageData });
});
namedPipeReadStream.on('data', (data) => {
const imageChunk = data.toString().trim();
const chunkLogLength = 10;
console.log(
`${serverUUID} image chunk: ${imageChunk.substring(
0,
chunkLogLength,
)}...${imageChunk.substring(imageChunk.length - chunkLogLength - 1)}`,
);
namedPipeReadStream.close(); imageData += imageChunk;
}); });
} catch (prepPipeError) { } catch (prepPipeError) {
console.log(`Failed to prepare named pipe; CAUSE: ${prepPipeError}`); console.log(`Failed to prepare named pipe; CAUSE: ${prepPipeError}`);
@ -114,8 +137,9 @@ export const getServerDetail: RequestHandler = (request, response) => {
SERVER_PATHS.usr.sbin['anvil-get-server-screenshot'].self, SERVER_PATHS.usr.sbin['anvil-get-server-screenshot'].self,
job_data: `server-uuid=${serverUUID} job_data: `server-uuid=${serverUUID}
request-host-uuid=${requestHostUUID} request-host-uuid=${requestHostUUID}
resize=${resizeArgs}`, resize=${resizeArgs}
job_name: `get_server_screenshot::${serverUUID}`, out-file-id=${epoch}`,
job_name: `get_server_screenshot::${serverUUID}::${epoch}`,
job_title: 'job_0356', job_title: 'job_0356',
job_description: 'job_0357', job_description: 'job_0357',
job_progress: 0, job_progress: 0,

Loading…
Cancel
Save