Experimental patch that makes Camel make a new connection each time a message is fetched



I really, really, really really,  ...

really hope people will test this patch A LOT.

It's quite gross what happens, but actually: it just works. 

I'm basically creating a new CamelImapStore instance, that will connect
on its own behalf, and I use that new store instance for getting the
message. Then I simply disconnect that connection, and I unreference the
worker instance.

Things that might go wrong: the password must be set in the ->url of the
instance. I will also tweak this a little bit to have the API of Camel
cope with all this in a nice way.

I had to make some private API of CamelImapStore public, like its
constructor for example.

I don't recommend doing this trick for other functionalities of Camel.
Nothing in Camel (except the getting of messages, after I reviewed it
line by line) is calculated on this way of working.

Please don't let this be a way for you to tell me: hey, just create a
new connection like what you did for the camel_folder_get_message
functionality: no ... this is an exception.



-- 
Philip Van Hoof, software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://www.pvanhoof.be/blog



Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c	(revision 1837)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c	(working copy)
@@ -374,6 +374,16 @@
 	}
 }
 
+
+void
+camel_imap_store_construct (CamelService *service, CamelSession *session,
+	   CamelProvider *provider, CamelURL *url,
+	   CamelException *ex)
+{
+	construct (service, session, provider, url, ex);
+}
+
+
 static int
 imap_setv (CamelObject *object, CamelException *ex, CamelArgV *args)
 {
@@ -1060,7 +1070,8 @@
 	{ NULL,            "imap",  IMAP_PORT,  MODE_CLEAR },
 };
 
-gboolean
+
+static gboolean
 connect_to_server_wrapper (CamelService *service, CamelException *ex)
 {
 	const char *ssl_mode;
@@ -1114,6 +1125,12 @@
 	return ret;
 }
 
+gboolean 
+camel_imap_service_connect (CamelService *service, CamelException *ex)
+{
+	return connect_to_server_wrapper (service, ex);
+}
+
 extern CamelServiceAuthType camel_imap_password_authtype;
 
 static GList *
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h	(revision 1837)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h	(working copy)
@@ -159,13 +159,17 @@
 
 ssize_t camel_imap_store_readline_nb (CamelImapStore *store, char **dest, CamelException *ex);
 ssize_t camel_imap_store_readline (CamelImapStore *store, char **dest, CamelException *ex);
-gboolean connect_to_server_wrapper (CamelService *service, CamelException *ex);
+gboolean camel_imap_service_connect (CamelService *service, CamelException *ex);
 
 gboolean camel_imap_store_restore_stream_buffer (CamelImapStore *store);
 
 void camel_imap_store_stop_idle (CamelImapStore *store);
 void camel_imap_store_start_idle (CamelImapStore *store);
 
+void
+camel_imap_store_construct (CamelService *service, CamelSession *session,
+	   CamelProvider *provider, CamelURL *url,
+	   CamelException *ex);
 
 #ifdef __cplusplus
 }
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c	(revision 1837)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c	(working copy)
@@ -3830,32 +3830,19 @@
 			      CamelFolderReceiveType type, gint param, CamelException *ex)
 {
 	CamelFolder *folder = CAMEL_FOLDER (imap_folder);
-	CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
+	CamelImapStore *store = NULL;
 	CamelStream *stream = NULL;
 	gboolean connected = FALSE, idle_rt = FALSE;
-	CamelException tex = CAMEL_EXCEPTION_INITIALISER, myex = CAMEL_EXCEPTION_INITIALISER;
-	ssize_t nread = 0; 
+	CamelException  tex = CAMEL_EXCEPTION_INITIALISER, 
+			myex = CAMEL_EXCEPTION_INITIALISER,
+			cex = CAMEL_EXCEPTION_INITIALISER;
+	ssize_t nread = 0; gboolean amcon = FALSE;
 	gchar *a_resp = NULL;
 
-	/* EXPUNGE responses have to modify the cache, which means
-	 * they have to grab the cache_lock while holding the
-	 * connect_lock.
-
-	 * Because getting the service lock may cause MUCH unecessary
-	 * delay when we already have the data locally, we do the
-	 * locking separately.  This could cause a race
-	 * getting the same data from the cache, but that is only
-	 * an inefficiency, and bad luck. */
-
 	CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
 
-	connected = camel_disco_store_check_online((CamelDiscoStore *)store, &tex);
+	connected = camel_disco_store_check_online(CAMEL_DISCO_STORE (folder->parent_store), &tex);
 
-	if (!store->istream || ((CamelObject *)store->istream)->ref_count <= 0)
-		connected = FALSE;
-	if (!store->ostream || ((CamelObject *)store->ostream)->ref_count <= 0)
-		connected = FALSE;
-	
 	if (connected && ((type & CAMEL_FOLDER_RECEIVE_FULL) && camel_imap_message_cache_is_partial (imap_folder->cache, uid)))
 		camel_imap_message_cache_remove (imap_folder->cache, uid);
 	else if (connected && ((type & CAMEL_FOLDER_RECEIVE_PARTIAL || type & CAMEL_FOLDER_RECEIVE_SIZE_LIMITED) 
@@ -3863,20 +3850,20 @@
 		camel_imap_message_cache_remove (imap_folder->cache, uid);
 	else
 	{
-	    stream = camel_imap_message_cache_get (imap_folder->cache, uid, section_text, ex);
-
-	    if (!stream && (!strcmp (section_text, "HEADER") || !strcmp (section_text, "0"))) 
-	    {
-		    camel_exception_clear (ex);
-		    stream = camel_imap_message_cache_get (imap_folder->cache, uid, "", ex);
-	    }
+		stream = camel_imap_message_cache_get (imap_folder->cache, uid, section_text, ex);
+		if (!stream && (!strcmp (section_text, "HEADER") || !strcmp (section_text, "0"))) 
+		{
+			camel_exception_clear (ex);
+			stream = camel_imap_message_cache_get (imap_folder->cache, uid, "", ex);
+		}
 	}
 	CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
-	
+
 	if (stream || cache_only)
 		return stream;
 
-	if (!camel_disco_store_check_online ((CamelDiscoStore*)store, ex)) {
+	if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (folder->parent_store), ex)) 
+	{
 		camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 				     _("This message is not currently available"));
 		CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
@@ -3884,10 +3871,35 @@
 	}
 	camel_exception_clear (ex);
 
-  CAMEL_SERVICE_REC_LOCK(store, connect_lock);
 
-	camel_exception_clear(ex);
+	store = CAMEL_IMAP_STORE (camel_object_new (CAMEL_IMAP_STORE_TYPE));
 
+	camel_imap_store_construct (CAMEL_SERVICE (store), 
+		camel_service_get_session (CAMEL_SERVICE (folder->parent_store)),
+		camel_service_get_provider (CAMEL_SERVICE (folder->parent_store)),
+		CAMEL_SERVICE (folder->parent_store)->url, ex);
+
+	if (camel_exception_is_set (ex))
+	{
+		g_critical ("ERR\n");
+	}
+
+	/* amcon = camel_imap_service_connect (CAMEL_SERVICE (store), ex); */
+	amcon = camel_service_connect (CAMEL_SERVICE (store), ex);
+
+	if (!amcon || camel_exception_is_set (ex) || !camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex)) 
+	{
+		camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+				     _("This message is not currently available"));
+		CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
+		return NULL;
+	}
+	camel_exception_clear (ex);
+
+printf ("You have a second connection !\n");
+
+  CAMEL_SERVICE_REC_LOCK(store, connect_lock); 
+
 	CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
 
 	if (type & CAMEL_FOLDER_RECEIVE_FULL)
@@ -4251,8 +4263,11 @@
 
 	CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
 
-  CAMEL_SERVICE_REC_UNLOCK(store, connect_lock);
+  CAMEL_SERVICE_REC_UNLOCK(store, connect_lock); 
 
+	camel_service_disconnect (CAMEL_SERVICE (store), TRUE, NULL);
+	camel_object_unref (CAMEL_OBJECT (store));
+
 	return stream;
 
 errorhander:
@@ -4271,8 +4286,13 @@
 	if (stream && ((CamelObject *)stream)->ref_count > 0)
 		camel_object_unref (CAMEL_OBJECT (stream));
 
+  if (store)
+  {
+
   CAMEL_SERVICE_REC_UNLOCK(store, connect_lock);
-
+	camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+	camel_object_unref (CAMEL_OBJECT (store));
+  }
 	return NULL;
 }
 
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c	(revision 1837)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c	(working copy)
@@ -271,6 +271,8 @@
 		store->command++, cmd);
 	len = strlen (full_cmd);
 
+printf ("-> %s\n", full_cmd);
+
 	nwritten = camel_stream_write (store->ostream, full_cmd, len);
 
 	/* g_mutex_unlock (store->stream_lock); */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]