Przeglądaj źródła

enable puppeteer config from env var

Futa Arai 5 miesięcy temu
rodzic
commit
bcec2254b5

+ 1 - 0
apps/pdf-converter/.env

@@ -1 +1,2 @@
 PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
+PUPPETEER_CLUSTER_CONFIG={"maxConcurrency":1, "concurrency": 2}

+ 2 - 2
apps/pdf-converter/docker/README.md

@@ -5,10 +5,10 @@ GROWI PDF Converter Official docker image
 [![Node CI for pdf-converter](https://github.com/growilabs/growi/actions/workflows/ci-pdf-converter.yml/badge.svg)](https://github.com/growilabs/growi/actions/workflows/ci-pdf-converter.yml) [![docker-pulls](https://img.shields.io/docker/pulls/growilabs/pdf-converter.svg)](https://hub.docker.com/r/growilabs/pdf-converter/)
 
 
-Supported tags and respective Dockerfile links
+Dockerfile link
 ------------------------------------------------
 
-* [`1.0.0`, `latest` (Dockerfile)](https://github.com/growilabs/growi/blob/master/apps/pdf-converter/docker/Dockerfile)
+https://github.com/growilabs/growi/blob/master/apps/pdf-converter/docker/Dockerfile
 
 
 What is GROWI PDF Converter used for?

+ 46 - 11
apps/pdf-converter/src/service/pdf-convert.ts

@@ -5,6 +5,7 @@ import { pipeline as pipelinePromise } from 'node:stream/promises';
 import { OnInit } from '@tsed/common';
 import { Service } from '@tsed/di';
 import { Logger } from '@tsed/logger';
+import type { PuppeteerNodeLaunchOptions } from 'puppeteer';
 import { Cluster } from 'puppeteer-cluster';
 
 interface PageInfo {
@@ -37,8 +38,6 @@ interface JobInfo {
 class PdfConvertService implements OnInit {
   private puppeteerCluster: Cluster | undefined;
 
-  private maxConcurrency = 1;
-
   private convertRetryLimit = 5;
 
   private tmpOutputRootDir = '/tmp/page-bulk-export';
@@ -287,20 +286,56 @@ class PdfConvertService implements OnInit {
   }
 
   /**
-   * Initialize puppeteer cluster
+   * Get puppeteer cluster configuration from environment variable
+   * @returns merged cluster configuration
    */
-  private async initPuppeteerCluster(): Promise<void> {
-    if (process.env.SKIP_PUPPETEER_INIT === 'true') return;
+  private getPuppeteerClusterConfig(): Record<string, any> {
+    // Default puppeteer options
+    const defaultPuppeteerOptions: PuppeteerNodeLaunchOptions = {
+      // ref) https://github.com/growilabs/growi/pull/10192
+      args: ['--no-sandbox'],
+    };
 
-    this.puppeteerCluster = await Cluster.launch({
-      concurrency: Cluster.CONCURRENCY_PAGE,
-      maxConcurrency: this.maxConcurrency,
+    // Default cluster configuration
+    const defaultConfig = {
+      concurrency: Cluster.CONCURRENCY_CONTEXT,
+      maxConcurrency: 1,
       workerCreationDelay: 10000,
+      puppeteerOptions: defaultPuppeteerOptions,
+    };
+
+    // Parse configuration from environment variable
+    let customConfig: Record<string, any> = {};
+    if (process.env.PUPPETEER_CLUSTER_CONFIG) {
+      try {
+        customConfig = JSON.parse(process.env.PUPPETEER_CLUSTER_CONFIG);
+      } catch (err) {
+        this.logger.warn(
+          'Failed to parse PUPPETEER_CLUSTER_CONFIG, using default values',
+          err,
+        );
+      }
+    }
+
+    // Merge configurations (customConfig overrides defaultConfig)
+    return {
+      ...defaultConfig,
+      ...customConfig,
       puppeteerOptions: {
-        // ref) https://github.com/growilabs/growi/pull/10192
-        args: ['--no-sandbox'],
+        ...defaultPuppeteerOptions,
+        ...customConfig.puppeteerOptions,
       },
-    });
+    };
+  }
+
+  /**
+   * Initialize puppeteer cluster
+   */
+  private async initPuppeteerCluster(): Promise<void> {
+    if (process.env.SKIP_PUPPETEER_INIT === 'true') return;
+
+    const config = this.getPuppeteerClusterConfig();
+    this.puppeteerCluster = await Cluster.launch(config);
 
     await this.puppeteerCluster.task(async ({ page, data: htmlString }) => {
       await page.setContent(htmlString, { waitUntil: 'domcontentloaded' });