Author: rfm
Date: Fri Jun 20 07:15:24 2014
New Revision: 37951

URL: http://svn.gna.org/viewcvs/gnustep?rev=37951&view=rev
Log:
Add code to limit idle connections in pool to the poll 'min' size.

Modified:
    libs/sqlclient/trunk/SQLClient.h
    libs/sqlclient/trunk/SQLClient.m
    libs/sqlclient/trunk/testPostgres.m

Modified: libs/sqlclient/trunk/SQLClient.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClient.h?rev=37951&r1=37950&r2=37951&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClient.h    (original)
+++ libs/sqlclient/trunk/SQLClient.h    Fri Jun 20 07:15:24 2014
@@ -383,14 +383,15 @@
   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 @@
  */
 - (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).
  */

Modified: libs/sqlclient/trunk/SQLClient.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClient.m?rev=37951&r1=37950&r2=37951&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClient.m    (original)
+++ libs/sqlclient/trunk/SQLClient.m    Fri Jun 20 07:15:24 2014
@@ -76,10 +76,11 @@
 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 @@
 
 + (void) initialize
 {
-  static id    modes[1];
-  
-  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];
+  if (Nil == SQLClientClass && [SQLClient class] == self)
+    {
+      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 @@
                     }
                 }
 
+             _lastStart = GSTickerTimeNow();
              [self backendConnect];
               /* On establishng a new connection, we must restore any
                * listen instructions in the backend.
@@ -1272,6 +1279,51 @@
       return [NSDate dateWithTimeIntervalSinceReferenceDate: _lastOperation];
     }
   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
@@ -1706,7 +1758,6 @@
   [lock lock];
   NS_DURING
     {
-      NSTimeInterval   start = 0.0;
       NSString         *statement;
       BOOL              isCommit = NO;
       BOOL              isRollback = NO;
@@ -1722,10 +1773,7 @@
           isRollback = YES;
         }
 
-      if (_duration >= 0)
-       {
-         start = GSTickerTimeNow();
-       }
+      _lastStart = GSTickerTimeNow();
       result = [self backendExecute: info];
       _lastOperation = GSTickerTimeNow();
       [_statements addObject: statement];
@@ -1733,7 +1781,7 @@
        {
          NSTimeInterval        d;
 
-         d = _lastOperation - start;
+         d = _lastOperation - _lastStart;
          if (d >= _duration)
            {
              if (isCommit || isRollback)
@@ -1814,19 +1862,14 @@
   [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 @@
 {
   NSMutableArray       *result;
   NSMutableDictionary  *md;
-  NSTimeInterval       start;
   GSCache              *c;
   id                   toCache;
 
@@ -2688,7 +2730,7 @@
   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 @@
        {
          NSTimeInterval        d;
 
-         d = _lastOperation - start;
+         d = _lastOperation - _lastStart;
          if (d >= _duration)
            {
              [self debug: @"Duration %g for query %@", d, stmt];

Modified: libs/sqlclient/trunk/testPostgres.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/testPostgres.m?rev=37951&r1=37950&r2=37951&view=diff
==============================================================================
--- libs/sqlclient/trunk/testPostgres.m (original)
+++ libs/sqlclient/trunk/testPostgres.m Fri Jun 20 07:15:24 2014
@@ -69,11 +69,13 @@
       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


_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to