1
- import { Cluster } from 'puppeteer-cluster' ;
1
+ import { Cluster as PoolpeteerCluster } from 'poolpeteer' ;
2
+ import { Cluster as PuppeteerCluster } from 'puppeteer-cluster' ;
2
3
import { ImageRenderOptions , RenderOptions } from '../types' ;
3
4
import { Browser , RenderResponse , RenderCSVResponse , Metrics } from './browser' ;
4
5
import { Logger } from '../logger' ;
@@ -10,12 +11,17 @@ enum RenderType {
10
11
}
11
12
12
13
interface ClusterOptions {
14
+ groupId ?: string ;
13
15
options : RenderOptions | ImageRenderOptions ;
14
16
renderType : RenderType ;
15
17
}
16
18
17
19
type ClusterResponse = RenderResponse | RenderCSVResponse ;
18
20
21
+ const contextPerRenderKey = 'contextPerRenderKey' ;
22
+
23
+ type Cluster < JobData = any , ReturnData = any > = PuppeteerCluster < JobData , ReturnData > | PoolpeteerCluster < JobData , ReturnData > ;
24
+
19
25
export class ClusteredBrowser extends Browser {
20
26
cluster : Cluster < ClusterOptions , ClusterResponse > ;
21
27
clusteringConfig : ClusteringConfig ;
@@ -25,21 +31,45 @@ export class ClusteredBrowser extends Browser {
25
31
super ( config , log , metrics ) ;
26
32
27
33
this . clusteringConfig = config . clustering ;
28
- this . concurrency = Cluster . CONCURRENCY_BROWSER ;
34
+ this . concurrency = PuppeteerCluster . CONCURRENCY_BROWSER ;
29
35
30
36
if ( this . clusteringConfig . mode === 'context' ) {
31
- this . concurrency = Cluster . CONCURRENCY_CONTEXT ;
37
+ this . concurrency = PuppeteerCluster . CONCURRENCY_CONTEXT ;
38
+ }
39
+
40
+ if ( this . clusteringConfig . mode === contextPerRenderKey ) {
41
+ this . concurrency = PoolpeteerCluster . CONCURRENCY_CONTEXT_PER_REQUEST_GROUP ;
32
42
}
33
43
}
34
44
35
- async start ( ) : Promise < void > {
45
+ shouldUsePoolpeteer ( ) : boolean {
46
+ return this . clusteringConfig . mode === contextPerRenderKey ;
47
+ }
48
+
49
+ async createCluster ( ) : Promise < Cluster < ClusterOptions , ClusterResponse > > {
36
50
const launcherOptions = this . getLauncherOptions ( { } ) ;
37
- this . cluster = await Cluster . launch ( {
51
+
52
+ const clusterOptions = {
38
53
concurrency : this . concurrency ,
54
+ workerShutdownTimeout : 5000 ,
55
+ monitor : this . clusteringConfig . monitor ,
39
56
maxConcurrency : this . clusteringConfig . maxConcurrency ,
40
57
timeout : this . clusteringConfig . timeout * 1000 ,
41
58
puppeteerOptions : launcherOptions ,
42
- } ) ;
59
+ } ;
60
+
61
+ // TODO use poolpeteer by default after initial release and testing (8.5?)
62
+ if ( this . shouldUsePoolpeteer ( ) ) {
63
+ this . log . debug ( 'Launching Browser cluster with poolpeteer' ) ;
64
+ return PoolpeteerCluster . launch ( clusterOptions ) ;
65
+ }
66
+
67
+ this . log . debug ( 'Launching Browser cluster with puppeteer-cluster' ) ;
68
+ return PuppeteerCluster . launch ( clusterOptions ) ;
69
+ }
70
+
71
+ async start ( ) : Promise < void > {
72
+ this . cluster = await this . createCluster ( ) ;
43
73
await this . cluster . task ( async ( { page, data } ) => {
44
74
if ( data . options . timezone ) {
45
75
// set timezone
@@ -61,13 +91,21 @@ export class ClusteredBrowser extends Browser {
61
91
} ) ;
62
92
}
63
93
94
+ private getGroupId = ( options : ImageRenderOptions | RenderOptions ) => {
95
+ if ( this . clusteringConfig . mode === contextPerRenderKey ) {
96
+ return `${ options . domain } ${ options . renderKey } ` ;
97
+ }
98
+
99
+ return undefined ;
100
+ } ;
101
+
64
102
async render ( options : ImageRenderOptions ) : Promise < RenderResponse > {
65
103
this . validateImageOptions ( options ) ;
66
- return this . cluster . execute ( { options, renderType : RenderType . PNG } ) ;
104
+ return this . cluster . execute ( { groupId : this . getGroupId ( options ) , options, renderType : RenderType . PNG } ) ;
67
105
}
68
106
69
107
async renderCSV ( options : RenderOptions ) : Promise < RenderCSVResponse > {
70
108
this . validateRenderOptions ( options ) ;
71
- return this . cluster . execute ( { options, renderType : RenderType . CSV } ) ;
109
+ return this . cluster . execute ( { groupId : this . getGroupId ( options ) , options, renderType : RenderType . CSV } ) ;
72
110
}
73
111
}
0 commit comments