-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.ts
78 lines (68 loc) · 1.63 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { Browser, launch } from 'puppeteer';
import { createPool, Options } from 'generic-pool';
export interface IBrowser extends Browser {
useCount?: number;
}
export interface IOptions extends Options {
maxUses?: number;
puppeteerArgs?: Object[];
validator?: () => Promise<Browser>;
}
const puppeteerPool = (
{
max = 10,
min = 2,
idleTimeoutMillis = 30000,
maxUses = 50,
testOnBorrow = true,
puppeteerArgs = [],
validator = (instance) => Promise.resolve(instance),
...otherConfig
} = <IOptions>{}) => {
const factory = {
create: () => launch(...puppeteerArgs)
.then((instance: IBrowser) => {
instance['useCount'] = 0;
return instance;
}),
destroy: instance => instance.close(),
validate: instance => validator(instance)
.then(valid => Promise.resolve(valid && (maxUses <= 0 || instance.useCount < maxUses)))
};
const config = {
max,
min,
idleTimeoutMillis,
testOnBorrow,
...otherConfig
};
let pool;
try {
pool = createPool<IBrowser>(factory, config);
} catch (e) {
throw e;
}
const genericAcquire = pool.acquire.bind(pool);
pool.acquire = () => genericAcquire().then((respource) => {
respource['useCount'] += 1;
return respource;
});
pool.use = (fn) => {
let resource;
return pool.acquire()
.then(r => {
resource = r;
return resource;
})
.then(fn)
.then((result) => {
pool.release(resource);
return result;
}, (err) => {
pool.release(resource);
throw err;
});
};
return pool;
};
export default puppeteerPool;