@@ -2,7 +2,9 @@ const IRISNative = require("@intersystems/intersystems-iris-native")
22import { Connection } from "@intersystems/intersystems-iris-native"
33
44export interface IRISConnection extends Connection {
5- query : ( queryString : string , argSets ?: any [ ] ) => any
5+ connectionId : string
6+ query : ( queryString : string , argSets ?: any [ ] ) => Promise < any >
7+ release : ( ) => Promise < void >
68}
79
810type IRISConnectionOptions = {
@@ -228,7 +230,6 @@ class ResultSet {
228230 } )
229231 this . rows . push ( row )
230232 }
231- // console.log("ResultSet rows fetched:", this.rows.length);
232233 }
233234}
234235
@@ -271,7 +272,7 @@ function normalizeArgs(args: any[]) {
271272
272273function createQuery ( connection : any ) {
273274 const iris = connection . createIris ( )
274- return function ( queryString : string , argSets : any [ ] ) : any {
275+ return async function ( queryString : string , argSets : any [ ] ) : Promise < any > {
275276 argSets =
276277 argSets && argSets . length && Array . isArray ( argSets [ 0 ] )
277278 ? argSets
@@ -304,10 +305,10 @@ function createQuery(connection: any) {
304305 }
305306 resultSet = st . execute ( ...args )
306307 if ( resultSet . Message ) {
307- return resultSet
308+ return Promise . resolve ( resultSet )
308309 }
309310 }
310- return resultSet
311+ return Promise . resolve ( resultSet )
311312 }
312313}
313314
@@ -322,4 +323,114 @@ IRISNative.createConnection = (
322323}
323324IRISNative . connect = IRISNative . createConnection
324325
325- export { IRISNative }
326+ class IRISConnectionPool {
327+ private options : IRISConnectionOptions
328+ private maxConnections : number
329+ private pool : IRISConnection [ ] = [ ]
330+ private activeConnections : Set < IRISConnection > = new Set ( )
331+ private connectionCount : number = 0
332+
333+ constructor ( options : IRISConnectionOptions , maxConnections : number = 5 ) {
334+ this . options = options
335+ this . maxConnections = maxConnections
336+ }
337+
338+ async getConnection ( ) : Promise < IRISConnection > {
339+ // Try to reuse an existing connection from pool
340+ if ( this . pool . length > 0 ) {
341+ const connection = this . pool . pop ( ) !
342+ this . activeConnections . add ( connection )
343+ return connection
344+ }
345+
346+ // Create new connection if under limit
347+ if ( this . connectionCount < this . maxConnections ) {
348+ try {
349+ const connection = await new Promise < IRISConnection > (
350+ ( resolve , reject ) => {
351+ try {
352+ const conn = IRISNative . createConnection (
353+ this . options ,
354+ )
355+ this . connectionCount ++
356+ conn . connectionId = `conn-${ this . connectionCount } `
357+ conn . release = ( ) => {
358+ this . releaseConnection ( conn )
359+ return Promise . resolve ( )
360+ }
361+ resolve ( conn )
362+ } catch ( error ) {
363+ reject ( error )
364+ }
365+ } ,
366+ )
367+ this . activeConnections . add ( connection )
368+ return connection
369+ } catch ( error ) {
370+ console . error ( "Failed to create connection:" , error )
371+ throw error
372+ }
373+ }
374+
375+ // Wait for a connection to become available
376+ // throw new Error("Max connections reached, please try again later.")
377+ return new Promise < IRISConnection > ( ( resolve ) => {
378+ const checkPool = ( ) : void => {
379+ if ( this . pool . length > 0 ) {
380+ const connection = this . pool . pop ( ) !
381+ this . activeConnections . add ( connection )
382+ resolve ( connection )
383+ } else {
384+ setTimeout ( checkPool , 100 )
385+ }
386+ }
387+ checkPool ( )
388+ } )
389+ }
390+
391+ releaseConnection ( connection : IRISConnection ) : void {
392+ if ( this . activeConnections . has ( connection ) ) {
393+ this . activeConnections . delete ( connection )
394+ this . pool . push ( connection )
395+ }
396+ }
397+
398+ async closeAll ( ) : Promise < void > {
399+ // Close active connections
400+ for ( const connection of this . activeConnections ) {
401+ try {
402+ connection . close ( )
403+ } catch ( error ) {
404+ console . error ( "Error closing active connection:" , error )
405+ }
406+ }
407+ this . activeConnections . clear ( )
408+
409+ // Close pooled connections
410+ for ( const connection of this . pool ) {
411+ try {
412+ connection . close ( )
413+ } catch ( error ) {
414+ console . error ( "Error closing pooled connection:" , error )
415+ }
416+ }
417+ this . pool . length = 0
418+ this . connectionCount = 0
419+
420+ // Force garbage collection if available
421+ if ( ( global as any ) . gc ) {
422+ ; ( global as any ) . gc ( )
423+ console . log ( "Forced garbage collection" )
424+ }
425+ }
426+
427+ getPoolStats ( ) : { active : number ; pooled : number ; total : number } {
428+ return {
429+ active : this . activeConnections . size ,
430+ pooled : this . pool . length ,
431+ total : this . connectionCount ,
432+ }
433+ }
434+ }
435+
436+ export { IRISNative , IRISConnectionPool }
0 commit comments