]> err.no Git - scalable-opengroupware.org/commitdiff
added pooling
authorhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 28 Sep 2004 15:32:48 +0000 (15:32 +0000)
committerhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 28 Sep 2004 15:32:48 +0000 (15:32 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@326 d1b88da0-ebda-0310-925b-ed51d893ca5b

SOGo/SoObjects/Mailer/ChangeLog
SOGo/SoObjects/Mailer/README [new file with mode: 0644]
SOGo/SoObjects/Mailer/SOGoMailManager.h
SOGo/SoObjects/Mailer/SOGoMailManager.m
SOGo/SoObjects/Mailer/Version

index 87a3e750ff74adf216ea298fa85a518742020bfc..a09f9772d79c72f2fcf4ba6e77c9928ed159a524 100644 (file)
@@ -1,5 +1,7 @@
 2004-09-28  Helge Hess  <helge.hess@opengroupware.org>
-       
+
+       * SOGoMailManager.m: added connection pooling (v0.9.10)
+
        * v0.9.9
        
        * SOGoMailBaseObject.m: added -mailManager method to retrieve the
diff --git a/SOGo/SoObjects/Mailer/README b/SOGo/SoObjects/Mailer/README
new file mode 100644 (file)
index 0000000..e61ff72
--- /dev/null
@@ -0,0 +1,13 @@
+# README for Mailer SoObjects
+
+Class Overview
+==============
+
+SOGoMailManager
+- backend class connecting to NGImap4, will probably move to SOGoLogic
+
+Defaults
+========
+
+SOGoEnableIMAP4Debug    YES|NO - enable/disable debugging in SOGoMailManager
+SOGoDisableIMAP4Pooling YES|NO - disable IMAP4 connection pooling
index 4fa50e5e376c16044d07205f26bdef21596e3589..0cf0e229b799810da06830329b6234f608348a10 100644 (file)
   Coordinates access to IMAP4 mailboxes, caches folder hierarchies, etc.
 */
 
-@class NSString, NSURL, NSArray;
+@class NSString, NSURL, NSArray, NSMutableDictionary, NSTimer;
 @class NGImap4Client;
 
 @interface SOGoMailManager : NSObject
 {
+  NSMutableDictionary *urlToEntry;
+  NSTimer *gcTimer;
 }
 
 + (id)defaultMailManager;
index 00b0cc42024147a84bdedb91862ef0266a1a3008..0cffcabcc1d473089685b484e73c60e38a93f500 100644 (file)
 #include "SOGoMailManager.h"
 #include "common.h"
 
+@interface SOGoMailConnectionEntry : NSObject
+{
+@public
+  NGImap4Client *client;
+  NSString      *password;
+  NSDate        *creationTime;
+  NSDictionary  *subfolders;
+}
+
+- (id)initWithClient:(NGImap4Client *)_client password:(NSString *)_pwd;
+
+/* accessors */
+
+- (NGImap4Client *)client;
+- (BOOL)isValidPassword:(NSString *)_pwd;
+
+- (NSDate *)creationTime;
+
+@end
+
 @implementation SOGoMailManager
 
-static BOOL debugOn = YES;
+static BOOL           debugOn    = YES;
+static BOOL           poolingOff = NO;
+static NSTimeInterval PoolScanInterval = 5 * 60;
+
++ (void)initialize {
+  NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+  
+  debugOn    = [ud boolForKey:@"SOGoEnableIMAP4Debug"];
+  poolingOff = [ud boolForKey:@"SOGoDisableIMAP4Pooling"];
+}
 
 + (id)defaultMailManager {
   static SOGoMailManager *manager = nil; // THREAD
@@ -33,19 +62,65 @@ static BOOL debugOn = YES;
   return manager;
 }
 
+- (id)init {
+  if ((self = [super init])) {
+    if (!poolingOff) {
+      self->urlToEntry = [[NSMutableDictionary alloc] initWithCapacity:256];
+    }
+    
+    self->gcTimer = [[NSTimer scheduledTimerWithTimeInterval:
+                               PoolScanInterval
+                             target:self selector:@selector(_garbageCollect:)
+                             userInfo:nil repeats:YES] retain];
+  }
+  return self;
+}
+
 - (void)dealloc {
+  if (self->gcTimer) [self->gcTimer invalidate];
+  [self->gcTimer release];
+  
+  [self->urlToEntry release];
   [super dealloc];
 }
 
+/* cache */
+
+- (id)cacheKeyForURL:(NSURL *)_url {
+  // protocol, user, host, port
+  return [NSString stringWithFormat:@"%@://%@@%@:%@",
+                  [_url scheme], [_url user], [_url host], [_url port]];
+}
+
+- (void)_garbageCollect:(NSTimer *)_timer {
+  // TODO: scan for old IMAP4 channels
+  [self debugWithFormat:@"should collect IMAP4 channels (%d active)",
+         [self->urlToEntry count]];
+}
+
 /* client object */
 
 - (NGImap4Client *)imap4ClientForURL:(NSURL *)_url password:(NSString *)_pwd {
   // TODO: move to some global IMAP4 connection pool manager
+  SOGoMailConnectionEntry *entry;
   NGImap4Client *client;
   NSDictionary  *result;
+  NSString      *cacheKey;
   
   if (_url == nil)
     return nil;
+
+  cacheKey = [self cacheKeyForURL:_url];
+  
+  if ((entry = [self->urlToEntry objectForKey:cacheKey]) != nil) {
+    if ([entry isValidPassword:_pwd]) {
+      [self debugWithFormat:@"reused IMAP4 connection for URL: %@", _url];
+      return [entry client];
+    }
+    
+    /* different password, password could have changed! */
+    entry = nil;
+  }
   
   if ((client = [NGImap4Client clientWithURL:_url]) == nil)
     return nil;
@@ -55,7 +130,12 @@ static BOOL debugOn = YES;
     [self logWithFormat:@"ERROR: IMAP4 login failed!"];
     return nil;
   }
-  
+
+  [self debugWithFormat:@"created new IMAP4 connection for URL: %@", _url];
+  entry = [[SOGoMailConnectionEntry alloc] initWithClient:client 
+                                          password:_pwd];
+  [self->urlToEntry setObject:entry forKey:cacheKey];
+  [entry release]; entry = nil;
   return client;
 }
 
@@ -142,3 +222,46 @@ static BOOL debugOn = YES;
 }
 
 @end /* SOGoMailManager */
+
+@implementation SOGoMailConnectionEntry
+
+- (id)initWithClient:(NGImap4Client *)_client password:(NSString *)_pwd {
+  if (_client == nil || _pwd == nil) {
+    [self release];
+    return nil;
+  }
+  
+  if ((self = [super init])) {
+    self->client   = [_client retain];
+    self->password = [_pwd    copy];
+
+    self->creationTime = [[NSDate alloc] init];
+  }
+  return self;
+}
+- (id)init {
+  return [self initWithClient:nil password:nil];
+}
+
+- (void)dealloc {
+  [self->creationTime release];
+  [self->subfolders   release];
+  [self->password     release];
+  [self->client       release];
+  [super dealloc];
+}
+
+/* accessors */
+
+- (NGImap4Client *)client {
+  return self->client;
+}
+- (BOOL)isValidPassword:(NSString *)_pwd {
+  return [self->password isEqualToString:_pwd];
+}
+
+- (NSDate *)creationTime {
+  return self->creationTime;
+}
+
+@end /* SOGoMailConnectionEntry */
index 81be7eb6e79defb0b93e0ca78f8a44c310c033c2..317960a726fc24e656b0d801367866c318018c26 100644 (file)
@@ -1,3 +1,3 @@
 # $Id$
 
-SUBMINOR_VERSION:=9
+SUBMINOR_VERSION:=10