| 137 | */ |
| 138 | @injectable({scope: BindingScope.SINGLETON}) |
| 139 | export class PoolingService<T> implements LifeCycleObserver { |
| 140 | private readonly factory: PoolFactory<T>; |
| 141 | /** |
| 142 | * The resource pool |
| 143 | */ |
| 144 | readonly pool: Pool<T>; |
| 145 | |
| 146 | constructor( |
| 147 | @inject.context() readonly context: Context, |
| 148 | @config() private options: PoolingServiceOptions<T>, |
| 149 | ) { |
| 150 | let factory = this.options.factory; |
| 151 | if (typeof factory === 'function') { |
| 152 | factory = factory(this.context); |
| 153 | } |
| 154 | this.factory = factory; |
| 155 | this.options = {...options, factory}; |
| 156 | this.pool = createPool(factory, { |
| 157 | max: 8, // Default to 8 instances |
| 158 | ...this.options.poolOptions, |
| 159 | // Disable `autostart` so that it follows LoopBack application life cycles |
| 160 | autostart: false, |
| 161 | }); |
| 162 | } |
| 163 | |
| 164 | /** |
| 165 | * Start the pool |
| 166 | */ |
| 167 | start() { |
| 168 | if (this.options.poolOptions?.autostart !== false) { |
| 169 | debug('Starting pool for context %s', this.context.name); |
| 170 | this.pool.start(); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | /** |
| 175 | * Stop the pool |
| 176 | */ |
| 177 | async stop() { |
| 178 | debug('Stopping pool for context %s', this.context.name); |
| 179 | if (this.pool == null) return; |
| 180 | await this.pool.drain(); |
| 181 | await this.pool.clear(); |
| 182 | } |
| 183 | |
| 184 | /** |
| 185 | * Acquire a new instance |
| 186 | * @param requestCtx - Optional request context, default to the owning context |
| 187 | */ |
| 188 | async acquire(requestCtx: Context = this.context) { |
| 189 | debug('Acquiring a resource from the pool for context %s', requestCtx.name); |
| 190 | const resource = await this.pool.acquire(); |
| 191 | |
| 192 | try { |
| 193 | // Try factory-level acquire hook first |
| 194 | if (this.factory.acquire) { |
| 195 | await this.factory.acquire(resource, requestCtx); |
| 196 | } else { |
nothing calls this directly
no outgoing calls
no test coverage detected