[evolution-patches] Patch for 64673 (free busy for users outside POA ) and some performance boosters for initial loading



hi,

 the adjoining patch contains the fix for 64673 - to allow eds to resend
f/b requests for outstanding users (outside POA) in the server response.
Also, added code to improve first-time GW calendar loading performance,
by fetching the items in Latest First order, populating the cache in a
separate thread that does not block the backend open call, updating the
items to evolution as they get processed without waiting for the entire
cache to be populated.
A marker is now used to flag the cache as populated as the timezone
element is not a reliable indicator anymore (now evo gets a chance to
add the default timezone even to an empty cache before the cache_init
has a chance to examine the cache).

kindly review the same.

thanks,
harish
Index: servers/groupwise/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/ChangeLog,v
retrieving revision 1.72
diff -u -p -r1.72 ChangeLog
--- servers/groupwise/ChangeLog	11 Oct 2004 08:35:51 -0000	1.72
+++ servers/groupwise/ChangeLog	12 Oct 2004 14:55:29 -0000
@@ -1,3 +1,12 @@
+2004-10-12  Harish Krishnaswamy  <kharish novell com>
+
+	* e-gw-connection.[ch]: (e_gw_connection_get_container_list) : The
+	argument should be "recurse" not "recursive".
+	(e_gw_connection_position_cursor): Add a function to position the cursor
+	at the desired offset.
+	(e_gw_connection_read_cursor): Set the cursor at end and direction set
+	to reverse - so items can be fetched Latest First.
+
 2004-10-10  Harish Krishnaswamy  <kharish novell com>
 
 	* e-gw-connection.c: (e_gw_connection_new): Add a static
Index: servers/groupwise/e-gw-connection.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-connection.c,v
retrieving revision 1.85
diff -u -p -r1.85 e-gw-connection.c
--- servers/groupwise/e-gw-connection.c	11 Oct 2004 08:35:51 -0000	1.85
+++ servers/groupwise/e-gw-connection.c	12 Oct 2004 14:55:30 -0000
@@ -422,7 +422,7 @@ e_gw_connection_get_container_list (EGwC
         }
 
         e_gw_message_write_string_parameter (msg, "parent", NULL, "folders");
-	e_gw_message_write_string_parameter (msg, "recursive", NULL, "true");
+	e_gw_message_write_string_parameter (msg, "recurse", NULL, "1");
 	e_gw_message_write_footer (msg);
 
         /* send message to server */
@@ -1657,6 +1657,36 @@ e_gw_connection_destroy_cursor (EGwConne
 
 
 EGwConnectionStatus
+e_gw_connection_position_cursor (EGwConnection *cnc, const char *container, int cursor, const char *seek, int offset)
+{
+	SoupSoapMessage *msg;
+	SoupSoapResponse *response;
+        EGwConnectionStatus status;
+
+	g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
+	g_return_val_if_fail ((container != NULL), E_GW_CONNECTION_STATUS_UNKNOWN);
+
+	msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "positionCursorRequest");
+	e_gw_message_write_string_parameter (msg, "container", NULL, container);
+	e_gw_message_write_int_parameter (msg, "cursor", NULL, cursor);
+	e_gw_message_write_string_parameter (msg, "seek", NULL, seek);
+	e_gw_message_write_int_parameter (msg, "offset", NULL, offset);
+	
+	e_gw_message_write_footer (msg);
+
+	response = e_gw_connection_send_message (cnc, msg);
+        if (!response) {
+                g_object_unref (msg);
+                return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
+        }
+	
+	status = e_gw_connection_parse_response_status (response);
+	g_object_unref (response);
+        g_object_unref (msg);
+	return status;
+}
+
+EGwConnectionStatus
 e_gw_connection_read_cursor (EGwConnection *cnc, const char *container, int cursor, int forward, int count, GList **item_list)
 {
 	SoupSoapMessage *msg;
@@ -1672,7 +1702,7 @@ e_gw_connection_read_cursor (EGwConnecti
 	e_gw_message_write_int_parameter (msg, "cursor", NULL, cursor);
 	/* there is problem in read curosr if you set this, uncomment after the problem 
 	   is fixed in server */
-	//	e_gw_message_write_int_parameter (msg, "forward", NULL, forward);
+	e_gw_message_write_int_parameter (msg, "forward", NULL, forward);
 	e_gw_message_write_int_parameter (msg, "count", NULL, count);
 	
 	e_gw_message_write_footer (msg);
Index: servers/groupwise/e-gw-connection.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-connection.h,v
retrieving revision 1.37
diff -u -p -r1.37 e-gw-connection.h
--- servers/groupwise/e-gw-connection.h	5 Oct 2004 11:27:30 -0000	1.37
+++ servers/groupwise/e-gw-connection.h	12 Oct 2004 14:55:30 -0000
@@ -112,6 +112,7 @@ EGwConnectionStatus e_gw_connection_get_
 EGwConnectionStatus e_gw_connection_create_cursor (EGwConnection *cnc, const char *container, const char *view, EGwFilter *filter, int *cursor);
 EGwConnectionStatus e_gw_connection_destroy_cursor (EGwConnection *cnc, const char *container,  int cursor);
 EGwConnectionStatus e_gw_connection_read_cursor (EGwConnection *cnc, const char *container, int cursor, int forward, int count, GList **item_list);
+EGwConnectionStatus e_gw_connection_position_cursor (EGwConnection *cnc, const char *container, int cursor, const char *seek, int offset);
 
 EGwConnectionStatus e_gw_connection_get_quick_messages (EGwConnection *cnc, const char *container, const char *view, const char *start_date, const char *message_list, const char *item_types, const char *item_sources, int count, GSList **item_list);
 
Index: calendar/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/ChangeLog,v
retrieving revision 1.342
diff -u -p -r1.342 ChangeLog
--- calendar/ChangeLog	7 Oct 2004 14:32:04 -0000	1.342
+++ calendar/ChangeLog	12 Oct 2004 14:55:31 -0000
@@ -1,3 +1,30 @@
+2004-10-12  Harish Krishnaswamy  <kharish novell com>
+	
+	Fixes #64673 and added some performance boosters.
+	
+	* backends/groupwise/e-cal-backend-groupwise-utils.c:
+	(e_gw_connection_get_freebusy_info): Resend free/busy requests 
+	to server if there are outstanding users whose information is still
+	pending from the server. Keep trying for 2 minutes (average time
+	for obtaining the f/b information for users outside the POA).
+	* backends/groupwise/e-cal-backend-groupwise.c: 
+	(populate_cache):  Obtain the calendar items from server Latest First.
+	Update evolution as soon as the items are processed, without waiting
+	for the entire cache to be populated.
+	(get_deltas): remove compiler warning.
+	(cache_init): Use a marker to test the status of cache and obtain all
+	items only for initial population.  All subsequent sessions would only 
+	fetch the deltas from the server since the last cache modification time.
+	(connect_to_server): Populating the cache moved to a separate thread
+	that does not block the open calls to backend anymore.
+	(e_cal_backend_groupwise_create_object): Fixed a leak.
+	* libedata-cal/e-cal-backend-cache.[ch]:
+	(e_cal_backend_cache_get_keys): Removed unused variable.
+	(e_cal_backend_cache_set_marker),
+	(e_cal_backend_cache_get_marker): Marker accessors to label the cache as
+	populated or not. This helps in determining if all the items are to be 
+	loaded from the server or if we should just fetch the deltas. 
+
 2004-10-07  JP Rosevear  <jpr novell com>
   
   	* libecal/e-cal.c (e_cal_new_system_tasks): load the correct type
Index: calendar/backends/groupwise/e-cal-backend-groupwise-utils.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/backends/groupwise/e-cal-backend-groupwise-utils.c,v
retrieving revision 1.36
diff -u -p -r1.36 e-cal-backend-groupwise-utils.c
--- calendar/backends/groupwise/e-cal-backend-groupwise-utils.c	1 Oct 2004 12:04:20 -0000	1.36
+++ calendar/backends/groupwise/e-cal-backend-groupwise-utils.c	12 Oct 2004 14:55:31 -0000
@@ -916,6 +916,8 @@ e_gw_connection_get_freebusy_info (EGwCo
         EGwConnectionStatus status;
         SoupSoapParameter *param, *subparam;
         const char *session;
+	gboolean resend_request = TRUE;
+	int request_iteration = 0;
 
 	g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
 
@@ -925,6 +927,9 @@ e_gw_connection_get_freebusy_info (EGwCo
         if (status != E_GW_CONNECTION_STATUS_OK)
                 return status;
 
+	resend :
+	while (resend_request) {
+
         /* getFreeBusy */
         /* build the SOAP message */
 	msg = e_gw_message_new_with_header (e_gw_connection_get_uri (cnc),
@@ -955,6 +960,29 @@ e_gw_connection_get_freebusy_info (EGwCo
                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
         }
 
+	for (subparam = soup_soap_parameter_get_first_child_by_name (param, "freeBusyStats");
+	     subparam != NULL;
+	     subparam = soup_soap_parameter_get_next_child_by_name (subparam, "freeBusyStats")) {
+		SoupSoapParameter *param_outstanding;
+		const char *outstanding;
+
+		param_outstanding = soup_soap_parameter_get_first_child_by_name (subparam, "outstanding");
+		if (param_outstanding)
+			outstanding = soup_soap_parameter_get_string_value (param_outstanding);
+		/* Try 12 times - this is approximately 2 minutes of time to
+		 * obtain the free/busy information from the server */
+		if (strcmp (outstanding, "0") && (request_iteration < 12)) {
+			request_iteration++;
+			g_object_unref (msg);
+		        g_object_unref (response);
+			g_usleep (10000000);
+			goto resend;
+		}
+
+	}
+
+	resend_request = FALSE;
+
         for (subparam = soup_soap_parameter_get_first_child_by_name (param, "user");
 	     subparam != NULL;
 	     subparam = soup_soap_parameter_get_next_child_by_name (subparam, "user")) {
@@ -1058,6 +1086,8 @@ e_gw_connection_get_freebusy_info (EGwCo
 
         g_object_unref (msg);
         g_object_unref (response);
+
+	} /* end of while loop */
 
         /* closeFreeBusySession*/
         return close_freebusy_session (cnc, session);
Index: calendar/backends/groupwise/e-cal-backend-groupwise.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/backends/groupwise/e-cal-backend-groupwise.c,v
retrieving revision 1.98
diff -u -p -r1.98 e-cal-backend-groupwise.c
--- calendar/backends/groupwise/e-cal-backend-groupwise.c	5 Oct 2004 11:43:14 -0000	1.98
+++ calendar/backends/groupwise/e-cal-backend-groupwise.c	12 Oct 2004 14:55:32 -0000
@@ -67,7 +67,7 @@ static void e_cal_backend_groupwise_fina
 static ECalBackendClass *parent_class = NULL;
 
 /* Time interval in milliseconds for obtaining changes from server and refresh the cache. */
-#define CACHE_REFRESH_INTERVAL 60000
+#define CACHE_REFRESH_INTERVAL 30000
 #define CURSOR_ITEM_LIMIT 100
 
 EGwConnection *
@@ -114,8 +114,10 @@ populate_cache (ECalBackendGroupwise *cb
         GList *list = NULL, *l;
 	gboolean done = FALSE;
 	int cursor = 0;
+	icalcomponent_kind kind;
 	
 	priv = cbgw->priv;
+	kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbgw));
 	
 	if (!mutex) {
 		mutex = g_mutex_new ();
@@ -137,9 +139,15 @@ populate_cache (ECalBackendGroupwise *cb
                 return status;
         }
 	
+	status = e_gw_connection_position_cursor (priv->cnc, priv->container_id, cursor, "end", 0);
+	if (status != E_GW_CONNECTION_STATUS_OK) {
+		e_cal_backend_groupwise_notify_error_code (cbgw, status);
+		g_mutex_unlock (mutex);
+                return status;
+        }
 	while (!done) {
 		
-		status = e_gw_connection_read_cursor (priv->cnc, priv->container_id, cursor, 1, CURSOR_ITEM_LIMIT, &list);
+		status = e_gw_connection_read_cursor (priv->cnc, priv->container_id, cursor, -1, CURSOR_ITEM_LIMIT, &list);
 		if (status != E_GW_CONNECTION_STATUS_OK) {
 			e_cal_backend_groupwise_notify_error_code (cbgw, status);
 			g_mutex_unlock (mutex);
@@ -155,9 +163,11 @@ populate_cache (ECalBackendGroupwise *cb
 				char *comp_str;
 				
 				e_cal_component_commit_sequence (comp);
-				comp_str = e_cal_component_get_as_string (comp);	
-				e_cal_backend_notify_object_created (E_CAL_BACKEND (cbgw), comp_str);
-				g_free (comp_str);
+				if (kind == icalcomponent_isa (e_cal_component_get_icalcomponent (comp))) {
+					comp_str = e_cal_component_get_as_string (comp);	
+					e_cal_backend_notify_object_created (E_CAL_BACKEND (cbgw), (const char *) comp_str);
+					g_free (comp_str);
+				}
 				e_cal_backend_cache_put_component (priv->cache, comp);
 				g_object_unref (comp);
 			}
@@ -186,7 +196,7 @@ get_deltas (gpointer handle)
 	GSList *item_list, *cache_keys, *l;
 	const char *cache_file_name;
 	char *comp_str;
-	static time_t mod_time = NULL;
+	static time_t mod_time = 0;
 	GTimeVal time_val;
 	char time_string[100];
 	const struct tm *tm;
@@ -358,17 +368,80 @@ form_uri (ESource *source)
 
 }
 
+static ECalBackendSyncStatus
+cache_init (ECalBackendGroupwise *cbgw)
+{
+	ECalBackendGroupwisePrivate *priv = cbgw->priv;
+	EGwConnectionStatus cnc_status;
+	icalcomponent_kind kind;
+
+	kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbgw));
 
+	g_message ("Entered cache_init stage\n");
+
+	/* We poke the cache for a default timezone. Its
+	 * absence indicates that the cache file has not been
+	 * populated before. */
+	if (!e_cal_backend_cache_get_marker (priv->cache)) {
+		/* Populate the cache for the first time.*/
+		/* start a timed polling thread set to 1 minute*/
+		cnc_status = populate_cache (cbgw);
+		if (cnc_status != E_GW_CONNECTION_STATUS_OK) {
+			g_warning (G_STRLOC ": Could not populate the cache");
+			/*FIXME  why dont we do a notify here */
+			return GNOME_Evolution_Calendar_PermissionDenied;
+		} else {
+			e_cal_backend_cache_set_marker (priv->cache);
+			priv->timeout_id = g_timeout_add (CACHE_REFRESH_INTERVAL, (GSourceFunc) get_deltas, (gpointer) cbgw);
+			priv->mode = CAL_MODE_REMOTE;
+			return GNOME_Evolution_Calendar_Success;
+		}
+	} else {
+		GList *cache_items = NULL, *l;
+		/* notify the ecal about the objects already in cache */
+		g_message ("updating views from cache\n");
+		cache_items = e_cal_backend_cache_get_components (priv->cache);
+		
+		for (l = cache_items; l; l = g_list_next (l)) {
+			ECalComponent *comp = E_CAL_COMPONENT (l->data);
+			char *cal_string;
+
+			if (kind == icalcomponent_isa (e_cal_component_get_icalcomponent (comp))) {
+				cal_string = e_cal_component_get_as_string (comp);
+				g_message ("Adding \n%s\n", cal_string);
+				e_cal_backend_notify_object_created (E_CAL_BACKEND (cbgw), cal_string);
+				g_free (cal_string);
+			}
+			g_object_unref (comp);
+		}		
+		if (cache_items)
+			g_list_free (cache_items);
+		g_message ("updated views from cache\n");
+		
+		/* get the deltas from the cache */
+		if (get_deltas (cbgw)) {
+			priv->timeout_id = g_timeout_add (CACHE_REFRESH_INTERVAL, (GSourceFunc) get_deltas, (gpointer) cbgw);
+			priv->mode = CAL_MODE_REMOTE;
+			return GNOME_Evolution_Calendar_Success;
+		} else {
+			g_warning (G_STRLOC ": Could not populate the cache");
+			/*FIXME  why dont we do a notify here */
+			return GNOME_Evolution_Calendar_PermissionDenied;	
+		}
+	}
+	
+}
 
 static ECalBackendSyncStatus
 connect_to_server (ECalBackendGroupwise *cbgw)
 {
 	char *real_uri;
 	ECalBackendGroupwisePrivate *priv;
-	EGwConnectionStatus cnc_status;
 	ESource *source;
 	const char *use_ssl;
 	char *http_uri;
+	GThread *thread;
+	GError *error = NULL;
 	priv = cbgw->priv;
 
 	source = e_cal_backend_get_source (E_CAL_BACKEND (cbgw));
@@ -427,38 +500,18 @@ connect_to_server (ECalBackendGroupwise 
 				e_cal_backend_notify_error (E_CAL_BACKEND (cbgw), _("Could not create cache file"));
 				return GNOME_Evolution_Calendar_OtherError;
 			}
-			
-			/* read the default timezone*/
-			priv->default_zone = e_cal_backend_cache_get_default_timezone (priv->cache);
 
-			/* We poke the cache for a default timezone. Its
-			 * absence indicates that the cache file has not been
-			 * populated before. */
-			if (!priv->default_zone) {
-				/* Populate the cache for the first time.*/
-				/* start a timed polling thread set to 10 minutes*/
-				cnc_status = populate_cache (cbgw);
-				if (cnc_status != E_GW_CONNECTION_STATUS_OK) {
-					g_warning (G_STRLOC ": Could not populate the cache");
-					/*FIXME  why dont we do a notify here */
-					return GNOME_Evolution_Calendar_PermissionDenied;
-				} else {
-					priv->timeout_id = g_timeout_add (CACHE_REFRESH_INTERVAL, (GSourceFunc) get_deltas, (gpointer) cbgw);
-					priv->mode = CAL_MODE_REMOTE;
-					return GNOME_Evolution_Calendar_Success;
-				}
-			} else {
-				/* get the deltas from the cache */
-				if (get_deltas (cbgw)) {
-					priv->timeout_id = g_timeout_add (CACHE_REFRESH_INTERVAL, (GSourceFunc) get_deltas, (gpointer) cbgw);
-					priv->mode = CAL_MODE_REMOTE;
-					return GNOME_Evolution_Calendar_Success;
-				} else {
-					g_warning (G_STRLOC ": Could not populate the cache");
-					/*FIXME  why dont we do a notify here */
-					return GNOME_Evolution_Calendar_PermissionDenied;	
-				}
+			/* spawn a new thread for opening the calendar */
+			thread = g_thread_create ((GThreadFunc) cache_init, cbgw, FALSE, &error);
+			if (!thread) {
+				g_warning (G_STRLOC ": %s", error->message);
+				g_error_free (error);
+
+				e_cal_backend_notify_error (E_CAL_BACKEND (cbgw), _("Could not create thread for populating cache"));
+				return GNOME_Evolution_Calendar_OtherError;
 			}
+
+			
 		} else {
 			e_cal_backend_notify_error (E_CAL_BACKEND (cbgw), _("Authentication failed"));
 			return GNOME_Evolution_Calendar_AuthenticationFailed;
@@ -1240,7 +1293,7 @@ e_cal_backend_groupwise_create_object (E
 				if (i != 0) {
 					char *temp;
 					temp = e_cal_component_get_as_string (e_cal_comp);
-					e_cal_backend_notify_object_created (E_CAL_BACKEND (cbgw), g_strdup(temp));
+					e_cal_backend_notify_object_created (E_CAL_BACKEND (cbgw), temp);
 					g_free (temp);
 				}
 
Index: calendar/libedata-cal/e-cal-backend-cache.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libedata-cal/e-cal-backend-cache.c,v
retrieving revision 1.17
diff -u -p -r1.17 e-cal-backend-cache.c
--- calendar/libedata-cal/e-cal-backend-cache.c	22 Sep 2004 16:41:07 -0000	1.17
+++ calendar/libedata-cal/e-cal-backend-cache.c	12 Oct 2004 14:55:32 -0000
@@ -586,9 +586,23 @@ e_cal_backend_cache_remove_timezone (ECa
 GSList *
 e_cal_backend_cache_get_keys (ECalBackendCache *cache)
 {
-	char *comp_str;
-        
         /* return null if cache is not a valid Backend Cache.  */
 	g_return_val_if_fail (E_IS_CAL_BACKEND_CACHE (cache), NULL);
         return e_file_cache_get_keys (E_FILE_CACHE (cache));
+}
+
+void
+e_cal_backend_cache_set_marker (ECalBackendCache *cache)
+{
+	g_return_if_fail (E_IS_CAL_BACKEND_CACHE (cache));
+	e_file_cache_add_object (E_FILE_CACHE (cache), "populated", "TRUE");
+}
+
+const char *
+e_cal_backend_cache_get_marker (ECalBackendCache *cache)
+{
+	g_return_val_if_fail (E_IS_CAL_BACKEND_CACHE (cache), NULL);
+	if (e_file_cache_get_object (E_FILE_CACHE (cache), "populated"))
+		return "";
+	return NULL;
 }
Index: calendar/libedata-cal/e-cal-backend-cache.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libedata-cal/e-cal-backend-cache.h,v
retrieving revision 1.11
diff -u -p -r1.11 e-cal-backend-cache.h
--- calendar/libedata-cal/e-cal-backend-cache.h	22 Sep 2004 16:41:07 -0000	1.11
+++ calendar/libedata-cal/e-cal-backend-cache.h	12 Oct 2004 14:55:32 -0000
@@ -66,6 +66,8 @@ icaltimezone       *e_cal_backend_cache_
 
 GSList             *e_cal_backend_cache_get_keys (ECalBackendCache *cache);
 
+const char         *e_cal_backend_cache_get_marker (ECalBackendCache *cache);
+void                e_cal_backend_cache_set_marker (ECalBackendCache *cache);
 
 G_END_DECLS
 


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