diff --git a/ChangeLog b/ChangeLog index f56bd64..061ea9b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2015-05-27 Richard Frith-Macdonald + + * Postgres.m: bugfixes + * SQLClient.m: bugfix for finding oldest idle connection + * SQLClientPool.m: implement method to disconnect idle connections + in pool. also check for clients being returned to pool while a + transaction is still in progress. + 2015-04-30 Richard Frith-Macdonald * Postgres.m: diff --git a/SQLClient.h b/SQLClient.h index 3c906ec..1087d14 100644 --- a/SQLClient.h +++ b/SQLClient.h @@ -987,7 +987,7 @@ SQLCLIENT_PRIVATE recordType: (id)rtype listType: (id)ltype; -/** Releases a lock previously obtained using -lockbeforeDate: +/** Releases a lock previously obtained using -lockBeforeDate: */ - (void) unlock; diff --git a/SQLClientPool.m b/SQLClientPool.m index 91f87bd..579bbfd 100644 --- a/SQLClientPool.m +++ b/SQLClientPool.m @@ -37,9 +37,15 @@ #import #import "SQLClient.h" -/** Connections idle for morew than this time are candidates for purging. +/** Connections idle for more than this time are candidates for purging + * as long as there are at leas min connections open. */ -static NSTimeInterval purgeTime = 10.0; +static NSTimeInterval purgeMinTime = 10.0; + +/** Connections idle for more than this time are candidates for purging + * even if the number of open connections is less than or equal to min. + */ +static NSTimeInterval purgeAllTime = 300.0; @interface SQLClient(Pool) - (void) _clearPool: (SQLClientPool*)p; @@ -333,19 +339,26 @@ static NSTimeInterval purgeTime = 10.0; } } } - if (connected > min && nil != found - && [[found lastOperation] timeIntervalSinceNow] < -purgeTime) + if (nil != found) { - NS_DURING + NSTimeInterval age; + + age = -[[found lastOperation] timeIntervalSinceNow]; + if (age > purgeAllTime + || (connected > min && age > purgeMinTime)) { - [found disconnect]; - more = YES; + NS_DURING + { + [found disconnect]; + more = YES; + } + NS_HANDLER + { + NSLog(@"Error disconnecting client in pool: %@", + localException); + } + NS_ENDHANDLER } - NS_HANDLER - { - NSLog(@"Error disconnecting client in pool: %@", localException); - } - NS_ENDHANDLER } } [self _unlock]; @@ -495,6 +508,8 @@ static NSTimeInterval purgeTime = 10.0; - (BOOL) swallowClient: (SQLClient*)client { + BOOL disconnected = NO; + BOOL replaced = NO; BOOL found = NO; int index; @@ -507,7 +522,24 @@ static NSTimeInterval purgeTime = 10.0; found = YES; } } + if (YES == found && YES == [client isInTransaction]) + { + if (YES == [client lockBeforeDate: nil]) + { + disconnected = YES; + [client disconnect]; + [client unlock]; + } + else + { + replaced = YES; + c[index] = [[SQLClient alloc] initWithConfiguration: _config + name: _name + pool: self]; + } + } [self _unlock]; + if (_debugging > 2) { if (YES == found) @@ -519,6 +551,19 @@ static NSTimeInterval purgeTime = 10.0; NSLog(@"%@ rejects %p", self, client); } } + + if (YES == disconnected) + { + NSLog(@"ERROR: Disconnected client which was returned to pool" + @" while a transaction was in progress: %@", client); + } + else if (YES == replaced) + { + NSLog(@"ERROR: Replaced client which was returned to pool" + @" while a transaction was in progress: %@", client); + [client release]; + } + return found; }