Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
pool.js108 linesDownload Raw Back to dispatcher
1'use strict'
2
3const {
4  PoolBase,
5  kClients,
6  kNeedDrain,
7  kAddClient,
8  kGetDispatcher
9} = require('./pool-base')
10const Client = require('./client')
11const {
12  InvalidArgumentError
13} = require('../core/errors')
14const util = require('../core/util')
15const { kUrl, kInterceptors } = require('../core/symbols')
16const buildConnector = require('../core/connect')
17
18const kOptions = Symbol('options')
19const kConnections = Symbol('connections')
20const kFactory = Symbol('factory')
21
22function defaultFactory (origin, opts) {
23  return new Client(origin, opts)
24}
25
26class Pool extends PoolBase {
27  constructor (origin, {
28    connections,
29    factory = defaultFactory,
30    connect,
31    connectTimeout,
32    tls,
33    maxCachedSessions,
34    socketPath,
35    autoSelectFamily,
36    autoSelectFamilyAttemptTimeout,
37    allowH2,
38    ...options
39  } = {}) {
40    if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
41      throw new InvalidArgumentError('invalid connections')
42    }
43
44    if (typeof factory !== 'function') {
45      throw new InvalidArgumentError('factory must be a function.')
46    }
47
48    if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') {
49      throw new InvalidArgumentError('connect must be a function or an object')
50    }
51
52    if (typeof connect !== 'function') {
53      connect = buildConnector({
54        ...tls,
55        maxCachedSessions,
56        allowH2,
57        socketPath,
58        timeout: connectTimeout,
59        ...(autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined),
60        ...connect
61      })
62    }
63
64    super(options)
65
66    this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool)
67      ? options.interceptors.Pool
68      : []
69    this[kConnections] = connections || null
70    this[kUrl] = util.parseOrigin(origin)
71    this[kOptions] = { ...util.deepClone(options), connect, allowH2 }
72    this[kOptions].interceptors = options.interceptors
73      ? { ...options.interceptors }
74      : undefined
75    this[kFactory] = factory
76
77    this.on('connectionError', (origin, targets, error) => {
78      // If a connection error occurs, we remove the client from the pool,
79      // and emit a connectionError event. They will not be re-used.
80      // Fixes https://github.com/nodejs/undici/issues/3895
81      for (const target of targets) {
82        // Do not use kRemoveClient here, as it will close the client,
83        // but the client cannot be closed in this state.
84        const idx = this[kClients].indexOf(target)
85        if (idx !== -1) {
86          this[kClients].splice(idx, 1)
87        }
88      }
89    })
90  }
91
92  [kGetDispatcher] () {
93    for (const client of this[kClients]) {
94      if (!client[kNeedDrain]) {
95        return client
96      }
97    }
98
99    if (!this[kConnections] || this[kClients].length < this[kConnections]) {
100      const dispatcher = this[kFactory](this[kUrl], this[kOptions])
101      this[kAddClient](dispatcher)
102      return dispatcher
103    }
104  }
105}
106
107module.exports = Pool
108 
codekingpro/portable-devtools · Team Ai