From 26501cdafe90188de5a473d2a15822eb95c8186f Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Wed, 13 Oct 2010 13:21:16 +0000 Subject: [PATCH] Monotone-Parent: 9b8dbd42ad07c6401218185ae572a3918a455e0f Monotone-Revision: f141f31038bdfcf46fcde9a48d1473fd5e5763a4 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-10-13T13:21:16 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 10 +++++ SoObjects/Mailer/SOGoMailBaseObject.m | 61 ++++++++++++++++++--------- SoObjects/SOGo/SOGoCache.h | 7 +++ SoObjects/SOGo/SOGoCache.m | 16 +++++++ 4 files changed, 74 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 038838a3f..fc928d7fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-10-13 Wolfgang Sourdeau + + * SoObjects/Mailer/SOGoMailBaseObject.m (-imap4Connection): split + initialization of the connection is the new + "_createIMAP4Connection" method, make use of the cache below. + + * SoObjects/SOGo/SOGoCache.m (-registerIMAP4Connection:forKey:) + (-imap4ConnectionForKey:): new accessors that enabling the + per-request caching of IMAP4 connections, in a valid state or not. + 2010-10-12 Wolfgang Sourdeau * OpenChange/MAPIStoreContext.m (-setMemCtx): argument is now of diff --git a/SoObjects/Mailer/SOGoMailBaseObject.m b/SoObjects/Mailer/SOGoMailBaseObject.m index a0ebd65c9..875e9a9b7 100644 --- a/SoObjects/Mailer/SOGoMailBaseObject.m +++ b/SoObjects/Mailer/SOGoMailBaseObject.m @@ -30,6 +30,8 @@ #import #import +#import + #import "SOGoMailAccount.h" #import "SOGoMailManager.h" @@ -73,7 +75,7 @@ static BOOL debugOn = YES; { SOGoMailAccount *folder; - if ([container respondsToSelector:_cmd]) + if ([container respondsToSelector: _cmd]) folder = [container mailAccountFolder]; else { @@ -116,33 +118,52 @@ static BOOL debugOn = YES; return [NGImap4ConnectionManager defaultConnectionManager]; } -- (NGImap4Connection *) imap4Connection +- (NGImap4Connection *) _createIMAP4Connection { NGImap4ConnectionManager *manager; NSString *password; + NGImap4Connection *newConnection; + + [self imap4URL]; + manager = [self mailManager]; + password = [self imap4PasswordRenewed: NO]; + if (password) + { + newConnection = [manager connectionForURL: imap4URL + password: password]; + if (!newConnection) + { + [self logWithFormat: @"renewing imap4 password"]; + password = [self imap4PasswordRenewed: YES]; + if (password) + newConnection = [manager connectionForURL: imap4URL + password: password]; + } + } + if (!newConnection) + { + newConnection = (NGImap4Connection *) [NSNull null]; + [self errorWithFormat:@"Could not connect IMAP4"]; + } + + return newConnection; +} + +- (NGImap4Connection *) imap4Connection +{ + NSString *cacheKey; + SOGoCache *sogoCache; if (!imap4) { - [self imap4URL]; - manager = [self mailManager]; - password = [self imap4PasswordRenewed: NO]; - if (password) - { - imap4 = [manager connectionForURL: imap4URL - password: password]; - if (!imap4) - { - [self logWithFormat: @"renewing imap4 password"]; - password = [self imap4PasswordRenewed: YES]; - if (password) - imap4 = [manager connectionForURL: imap4URL - password: password]; - } - } + sogoCache = [SOGoCache sharedCache]; + cacheKey = [[self mailAccountFolder] nameInContainer]; + imap4 = [sogoCache imap4ConnectionForKey: cacheKey]; if (!imap4) { - imap4 = (NGImap4Connection *) [NSNull null]; - [self errorWithFormat:@"Could not connect IMAP4"]; + imap4 = [self _createIMAP4Connection]; + [sogoCache registerIMAP4Connection: imap4 + forKey: cacheKey]; } [imap4 retain]; } diff --git a/SoObjects/SOGo/SOGoCache.h b/SoObjects/SOGo/SOGoCache.h index 73d49c8d2..2845892c4 100644 --- a/SoObjects/SOGo/SOGoCache.h +++ b/SoObjects/SOGo/SOGoCache.h @@ -32,6 +32,8 @@ @class NSString; @class NSUserDefaults; +@class NGImap4Connection; + @class SOGoGroup; @class SOGoObject; @class SOGoUser; @@ -40,6 +42,7 @@ @interface SOGoCache : NSObject { NSMutableDictionary *localCache; + NSMutableDictionary *imap4Connections; NSMutableDictionary *cache; NSMutableDictionary *users; NSMutableDictionary *groups; @@ -68,6 +71,10 @@ - (id) groupNamed: (NSString *) groupName inDomain: (NSString *) domainName; +- (void) registerIMAP4Connection: (NGImap4Connection *) connection + forKey: (NSString *) key; +- (NGImap4Connection *) imap4ConnectionForKey: (NSString *) key; + /* NSDictionary-like methods */ - (void) setValue: (NSString *) value forKey: (NSString *) key; - (NSString *) valueForKey: (NSString *) key; diff --git a/SoObjects/SOGo/SOGoCache.m b/SoObjects/SOGo/SOGoCache.m index 917bb7173..7c6df265a 100644 --- a/SoObjects/SOGo/SOGoCache.m +++ b/SoObjects/SOGo/SOGoCache.m @@ -75,6 +75,7 @@ static memcached_st *handle = NULL; - (void) killCache { [cache removeAllObjects]; + [imap4Connections removeAllObjects]; // This is essential for refetching the cached values in case something has changed // accross various sogod processes @@ -94,6 +95,7 @@ static memcached_st *handle = NULL; cache = [[NSMutableDictionary alloc] init]; users = [[NSMutableDictionary alloc] init]; groups = [[NSMutableDictionary alloc] init]; + imap4Connections = [[NSMutableDictionary alloc] init]; // localCache is used to avoid going all the time to the memcached // server during each request. We'll cache the value we got from @@ -141,6 +143,7 @@ static memcached_st *handle = NULL; [cache release]; [users release]; [groups release]; + [imap4Connections release]; [localCache release]; [super dealloc]; } @@ -230,6 +233,19 @@ static memcached_st *handle = NULL; return [groups objectForKey: [NSString stringWithFormat: @"%@+%@", groupName, domainName]]; } +- (void) registerIMAP4Connection: (NGImap4Connection *) connection + forKey: (NSString *) key +{ + if (connection) + [imap4Connections setObject: connection forKey: key]; + else + [imap4Connections removeObjectForKey: key]; +} + +- (NGImap4Connection *) imap4ConnectionForKey: (NSString *) key +{ + return [imap4Connections objectForKey: key]; +} // // For non-blocking cache method, see memcached_behavior_set and MEMCACHED_BEHAVIOR_NO_BLOCK