Просмотр исходного кода

Merge pull request #5986 from weseek/support/apply-expose-gc-at-runtime

support: Enable garbage collection at runtime with expose-gc package
Yuki Takei 3 лет назад
Родитель
Сommit
0fdb050585

+ 4 - 3
packages/app/package.json

@@ -11,7 +11,7 @@
     "clean": "npx -y shx rm -rf dist transpiled",
     "prebuild": "yarn cross-env NODE_ENV=production run-p clean resources:*",
     "postbuild": "npx -y shx mv transpiled/src dist && npx -y shx cp -r src/server/views dist/server/ && npx -y shx rm -rf transpiled",
-    "server": "yarn cross-env NODE_ENV=production node -r dotenv-flow/config --expose_gc dist/server/app.js",
+    "server": "yarn cross-env NODE_ENV=production node -r dotenv-flow/config dist/server/app.js",
     "server:ci": "yarn server --ci",
     "preserver": "yarn cross-env NODE_ENV=production yarn migrate",
     "migrate": "node -r dotenv-flow/config node_modules/.bin/migrate-mongo up",
@@ -19,7 +19,7 @@
     "dev": "run-p dev:client dev:server",
     "dev:client": "yarn cross-env NODE_ENV=development webpack --config config/webpack.dev.js --progress --watch",
     "dev:client:nowatch": "yarn cross-env NODE_ENV=development webpack --config config/webpack.dev.js",
-    "dev:server": "yarn cross-env NODE_ENV=development ts-node-dev --inspect --expose-gc -r tsconfig-paths/register -r dotenv-flow/config --transpile-only src/server/app.ts",
+    "dev:server": "yarn cross-env NODE_ENV=development ts-node-dev --inspect -r tsconfig-paths/register -r dotenv-flow/config --transpile-only src/server/app.ts",
     "predev:client": "yarn cross-env NODE_ENV=development run-p resources:*",
     "predev:server": "yarn cross-env NODE_ENV=development yarn dev:migrate:up",
     "dev:migrate-mongo": "yarn cross-env NODE_ENV=development yarn ts-node node_modules/.bin/migrate-mongo",
@@ -99,6 +99,7 @@
     "esa-node": "^0.2.2",
     "escape-string-regexp": "=4.0.0",
     "eslint-plugin-regex": "^1.8.0",
+    "expose-gc": "^1.0.0",
     "express": "^4.16.1",
     "express-bunyan-logger": "^1.3.3",
     "express-mongo-sanitize": "^2.1.0",
@@ -190,7 +191,6 @@
     "diff2html": "^3.1.2",
     "eazy-logger": "^3.1.0",
     "emoji-mart": "npm:panta82-emoji-mart@^3.0.1",
-    "markdown-it-emoji-mart": "^0.1.1",
     "eslint-plugin-cypress": "^2.12.1",
     "eslint-plugin-regex": "^1.8.0",
     "file-loader": "^5.0.2",
@@ -208,6 +208,7 @@
     "markdown-it-blockdiag": "^1.1.1",
     "markdown-it-drawio-viewer": "^1.3.1",
     "markdown-it-emoji": "^1.4.0",
+    "markdown-it-emoji-mart": "^0.1.1",
     "markdown-it-footnote": "^3.0.1",
     "markdown-it-mathjax": "^2.0.0",
     "markdown-it-named-headers": "^0.0.4",

+ 18 - 8
packages/app/src/server/service/import.js

@@ -1,23 +1,24 @@
+import gc from 'expose-gc/function';
+
 import loggerFactory from '~/utils/logger';
 
-const logger = loggerFactory('growi:services:ImportService'); // eslint-disable-line no-unused-vars
 const fs = require('fs');
 const path = require('path');
-
-const isIsoDate = require('is-iso-date');
-const parseISO = require('date-fns/parseISO');
-
 const { Writable, Transform } = require('stream');
+
 const JSONStream = require('JSONStream');
+const parseISO = require('date-fns/parseISO');
+const isIsoDate = require('is-iso-date');
+const mongoose = require('mongoose');
 const streamToPromise = require('stream-to-promise');
 const unzipper = require('unzipper');
 
-const mongoose = require('mongoose');
+const CollectionProgressingStatus = require('../models/vo/collection-progressing-status');
+const { createBatchStream } = require('../util/batch-stream');
 
 const { ObjectId } = mongoose.Types;
 
-const { createBatchStream } = require('../util/batch-stream');
-const CollectionProgressingStatus = require('../models/vo/collection-progressing-status');
+const logger = loggerFactory('growi:services:ImportService'); // eslint-disable-line no-unused-vars
 
 
 const BULK_IMPORT_SIZE = 100;
@@ -286,6 +287,15 @@ class ImportService {
 
           emitProgressEvent(collectionProgress, errors);
 
+          try {
+            // First aid to prevent unexplained memory leaks
+            logger.info('global.gc() invoked.');
+            gc();
+          }
+          catch (err) {
+            logger.error('fail garbage collection: ', err);
+          }
+
           callback();
         },
         final(callback) {

+ 3 - 1
packages/app/src/server/service/search-delegator/elasticsearch.ts

@@ -3,6 +3,7 @@ import { URL } from 'url';
 
 import elasticsearch6 from '@elastic/elasticsearch6';
 import elasticsearch7 from '@elastic/elasticsearch7';
+import gc from 'expose-gc/function';
 import mongoose from 'mongoose';
 import streamToPromise from 'stream-to-promise';
 
@@ -593,7 +594,8 @@ class ElasticsearchDelegator implements SearchDelegator<Data, ESTermsKey, ESQuer
         if (invokeGarbageCollection) {
           try {
             // First aid to prevent unexplained memory leaks
-            global.gc();
+            logger.info('global.gc() invoked.');
+            gc();
           }
           catch (err) {
             logger.error('fail garbage collection: ', err);

+ 5 - 0
yarn.lock

@@ -9448,6 +9448,11 @@ expect@^27.0.6:
     jest-message-util "^27.0.6"
     jest-regex-util "^27.0.6"
 
+expose-gc@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/expose-gc/-/expose-gc-1.0.0.tgz#ba0e825b390cc3e7ab38fc5b945cd2b4018584b3"
+  integrity sha512-ecOHrdm+zyOCGIwX18/1RHkUWgxDqGGRiGhaNC+42jReTtudbm2ID/DMa/wpaHwqy5YQHPZvsDqRM2F2iZ0uVA==
+
 express-bunyan-logger@^1.3.3:
   version "1.3.3"
   resolved "https://registry.yarnpkg.com/express-bunyan-logger/-/express-bunyan-logger-1.3.3.tgz#e76d9b3d598ca83a69b692a9839c7453d01b5010"