Add code to limit idle connections in pool to the poll 'min' size.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@37951 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2014-06-20 05:15:24 +00:00
parent dd264972c9
commit c84e989ab2
3 changed files with 102 additions and 49 deletions

View file

@ -383,14 +383,15 @@ SQLCLIENT_PRIVATE
NSString *_user; /** The configured user */
NSMutableArray *_statements; /** Uncommitted statements */
/**
* Timestamp of last operation.<br />
* Timestamp of completion of last operation.<br />
* Maintained by -simpleExecute: -simpleQuery:recordType:listType:
* and -cache:simpleQuery:recordType:listType:
* Also set for a failed connection attempt, but not reported by the
* -lastOperation method in that case.
*/
NSTimeInterval _lastOperation;
NSTimeInterval _duration;
NSTimeInterval _lastStart; /** Last op start or connect */
NSTimeInterval _duration; /** Duration logging threshold */
unsigned int _debugging; /** The current debugging level */
GSCache *_cache; /** The cache for query results */
NSThread *_cacheThread; /** Thread for cache queries */
@ -687,6 +688,14 @@ SQLCLIENT_PRIVATE
*/
- (NSDate*) lastOperation;
/** Compares the receiver with the other client to see which one has been
* inactive but connected for longest (if they are connected) and returns
* that instance.<br />
* If neither is idle but connected, the method returns nil.<br />
* In a tie, the method returns the other instance.
*/
- (SQLClient*) longestIdle: (SQLClient*)other;
/**
* Return the database reference name for this instance (or nil).
*/

View file

@ -76,10 +76,11 @@ NSString * const SQLClientDidDisconnectNotification
static NSNull *null = nil;
static NSArray *queryModes = nil;
static NSThread *mainThread = nil;
static Class NSStringClass = 0;
static Class NSArrayClass = 0;
static Class NSDateClass = 0;
static Class NSSetClass = 0;
static Class NSStringClass = Nil;
static Class NSArrayClass = Nil;
static Class NSDateClass = Nil;
static Class NSSetClass = Nil;
static Class SQLClientClass = Nil;
@interface _ConcreteSQLRecord : SQLRecord
{
@ -738,29 +739,34 @@ static unsigned int maxConnections = 8;
+ (void) initialize
{
static id modes[1];
modes[0] = NSDefaultRunLoopMode;
queryModes = [[NSArray alloc] initWithObjects: modes count: 1];
GSTickerTimeNow();
[SQLRecord class]; // Force initialisation
if (0 == clientsHash)
if (Nil == SQLClientClass && [SQLClient class] == self)
{
clientsHash = NSCreateHashTable(NSNonOwnedPointerHashCallBacks, 0);
clientsMap = NSCreateMapTable(NSObjectMapKeyCallBacks,
NSNonRetainedObjectMapValueCallBacks, 0);
clientsLock = [NSRecursiveLock new];
beginStatement = [[NSArray arrayWithObject: beginString] retain];
commitStatement = [[NSArray arrayWithObject: commitString] retain];
rollbackStatement = [[NSArray arrayWithObject: rollbackString] retain];
NSStringClass = [NSString class];
NSArrayClass = [NSArray class];
NSSetClass = [NSSet class];
[NSTimer scheduledTimerWithTimeInterval: 1.0
target: self
selector: @selector(_tick:)
userInfo: 0
repeats: YES];
static id modes[1];
SQLClientClass = self;
modes[0] = NSDefaultRunLoopMode;
queryModes = [[NSArray alloc] initWithObjects: modes count: 1];
GSTickerTimeNow();
[SQLRecord class]; // Force initialisation
if (0 == clientsHash)
{
clientsHash = NSCreateHashTable(NSNonOwnedPointerHashCallBacks, 0);
clientsMap = NSCreateMapTable(NSObjectMapKeyCallBacks,
NSNonRetainedObjectMapValueCallBacks, 0);
clientsLock = [NSRecursiveLock new];
beginStatement = [[NSArray arrayWithObject: beginString] retain];
commitStatement = [[NSArray arrayWithObject: commitString] retain];
rollbackStatement
= [[NSArray arrayWithObject: rollbackString] retain];
NSStringClass = [NSString class];
NSArrayClass = [NSArray class];
NSSetClass = [NSSet class];
[NSTimer scheduledTimerWithTimeInterval: 1.0
target: self
selector: @selector(_tick:)
userInfo: 0
repeats: YES];
}
}
}
@ -958,6 +964,7 @@ static unsigned int maxConnections = 8;
}
}
_lastStart = GSTickerTimeNow();
[self backendConnect];
/* On establishng a new connection, we must restore any
* listen instructions in the backend.
@ -1274,6 +1281,51 @@ static unsigned int maxConnections = 8;
return nil;
}
- (SQLClient*) longestIdle: (SQLClient*)other
{
NSTimeInterval t0;
NSTimeInterval t1;
NSAssert([other isKindOfClass: SQLClientClass], NSInvalidArgumentException);
t0 = _lastOperation;
if (t0 < _lastStart)
{
t0 = _lastStart;
}
if (NO == connected || 0 != _connectFails)
{
t0 = 0.0;
}
if (YES == [other isProxy])
{
t1 = 0.0;
}
else
{
t1 = other->_lastOperation;
if (t1 < other->_lastStart)
{
t1 = other->_lastStart;
}
if (NO == connected || 0 != other->_connectFails)
{
t1 = 0.0;
}
}
if (t0 <= 0.0 && t1 <= 0.0)
{
return nil;
}
if (t1 <= t0)
{
return other;
}
return self;
}
- (NSString*) name
{
return _name;
@ -1706,7 +1758,6 @@ static unsigned int maxConnections = 8;
[lock lock];
NS_DURING
{
NSTimeInterval start = 0.0;
NSString *statement;
BOOL isCommit = NO;
BOOL isRollback = NO;
@ -1722,10 +1773,7 @@ static unsigned int maxConnections = 8;
isRollback = YES;
}
if (_duration >= 0)
{
start = GSTickerTimeNow();
}
_lastStart = GSTickerTimeNow();
result = [self backendExecute: info];
_lastOperation = GSTickerTimeNow();
[_statements addObject: statement];
@ -1733,7 +1781,7 @@ static unsigned int maxConnections = 8;
{
NSTimeInterval d;
d = _lastOperation - start;
d = _lastOperation - _lastStart;
if (d >= _duration)
{
if (isCommit || isRollback)
@ -1814,19 +1862,14 @@ static unsigned int maxConnections = 8;
[lock lock];
NS_DURING
{
NSTimeInterval start = 0.0;
if (_duration >= 0)
{
start = GSTickerTimeNow();
}
_lastStart = GSTickerTimeNow();
result = [self backendQuery: stmt recordType: rtype listType: ltype];
_lastOperation = GSTickerTimeNow();
if (_duration >= 0)
{
NSTimeInterval d;
d = _lastOperation - start;
d = _lastOperation - _lastStart;
if (d >= _duration)
{
debug = [NSString stringWithFormat:
@ -2678,7 +2721,6 @@ static unsigned int maxConnections = 8;
{
NSMutableArray *result;
NSMutableDictionary *md;
NSTimeInterval start;
GSCache *c;
id toCache;
@ -2688,7 +2730,7 @@ static unsigned int maxConnections = 8;
md = [[NSThread currentThread] threadDictionary];
[md setObject: rtype forKey: @"SQLClientRecordType"];
[md setObject: ltype forKey: @"SQLClientListType"];
start = GSTickerTimeNow();
_lastStart = GSTickerTimeNow();
c = [self cache];
toCache = nil;
@ -2733,7 +2775,7 @@ static unsigned int maxConnections = 8;
{
NSTimeInterval d;
d = _lastOperation - start;
d = _lastOperation - _lastStart;
if (d >= _duration)
{
[self debug: @"Duration %g for query %@", d, stmt];

View file

@ -69,11 +69,13 @@ main()
nil]
];
sp = [[SQLClientPool alloc] initWithConfiguration: nil
name: @"test"
max: 2
min: 1];
db = [[sp autorelease] provideClient];
sp = [[[SQLClientPool alloc] initWithConfiguration: nil
name: @"test"
max: 2
min: 1] autorelease];
db = [sp provideClient];
[sp swallowClient: db];
db = [sp provideClient];
l = [Logger new];
[[NSNotificationCenter defaultCenter] addObserver: l