/soc/2012/sanket/statscollector-2.x.y: ceceac2c5c5f: Make public...

Sanket Agarwal sanket at soc.pidgin.im
Sun Aug 26 17:17:59 EDT 2012


Changeset: ceceac2c5c5f75b9d99c630c1ff3d57dbd4dec43
Author:	 Sanket Agarwal <sanket at soc.pidgin.im>
Date:	 2012-08-26 00:18 +0530
Branch:	 soc.2012.statscollector
URL: http://hg.pidgin.im/soc/2012/sanket/statscollector-2.x.y/rev/ceceac2c5c5f

Description:

Make public server cache refresh and update non-blocking

Currently all signal handlers and init of stats.xml were waiting
on public server cache to be refreshed. This is dangerous when
the server is down and the stats simply don't get accumalated.

Current patch makes the cache refresh non-blocking, that is each
refresh automatically sees the accounts and updates them with
names instead of hashes if required. Thus an account won't miss
out on a cache refresh simply because of race conditions/delay from
fetching of public server list.

I have also changed ``trusted'' to ``public''.

diffstat:

 libpurple/plugins/statscollector.c |  242 ++++++++++++++++--------------------
 1 files changed, 109 insertions(+), 133 deletions(-)

diffs (truncated from 369 to 300 lines):

diff --git a/libpurple/plugins/statscollector.c b/libpurple/plugins/statscollector.c
--- a/libpurple/plugins/statscollector.c
+++ b/libpurple/plugins/statscollector.c
@@ -40,15 +40,15 @@ enum
 
 /* Timeout */
 #define RESEND_SEC (24*3600)
-#define TRUSTED_CACHE_REFRESH (24*3600)
+#define PUBLIC_SERVER_CACHE_REFRESH (24*3600)
 
 /* Sending URL */
 #define SEND_URL "http://stats.pidgin.im/collect/"
-#define TRUSTED_URL "http://stats.pidgin.im/trusted/"
+#define PUBLIC_SERVER_URL "http://stats.pidgin.im/public/"
 
 /* Version of XML this plugin supports writing */
 
-#define STATS_XML_V "0.1" /* 0 -- Dev purposes */
+#define STATS_XML_V "0.2" /* 0 -- Dev purposes */
 
 /* POSIX compliance is an issue that I have looked into some detail now
  * It seems like presence of unistd.h and _POSIX_VERSION being defined
@@ -66,9 +66,9 @@ enum
 PurplePlugin *plugin_g;
 xmlnode *root_stats, *cpuinfo_xml, *ui_info;
 GHashTable *stats_acc_ht, *stats_plugins_ht, *stats_uis_ht;
-GHashTable *trusted_server_cache_ht=NULL;
+GHashTable *public_server_cache_ht=NULL;
 
-int save_timer = 0, send_handle = 0, pref_cb_id = -1;
+int save_timer = 0, send_handle = 0, pref_cb_id = -1, public_server_handle = 0;
 
 /* Types of Operating Systems */
 enum OS_TYPES {WINDOWS, APPLE, UNIX};
@@ -78,8 +78,9 @@ static void schedule_send(void);
 static gboolean send_stats();
 static gboolean plugin_load(PurplePlugin *);
 static gboolean plugin_unload(PurplePlugin *plugin);
-static gboolean refresh_trusted_cache(gpointer data);
+static gboolean refresh_public_server_cache(gpointer data);
 static xmlnode *init_stats();
+static void acc_sign_on_event(PurpleAccount *account);
 
 static void
 confirm_allow(){
@@ -194,7 +195,17 @@ schedule_stats_save(void){
 }
 
 static void
-refresh_trusted_cache_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message){
+refresh_accounts(){
+  /* Scan through each of the currently available accounts,
+   * and refresh them if we get more info
+   */
+  GList *loaded_accounts;
+  loaded_accounts = purple_accounts_get_all_active();
+  g_list_foreach(loaded_accounts, (GFunc)acc_sign_on_event, NULL);
+}
+
+static void
+refresh_public_server_cache_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message){
 
   /*
    * Check if the header has HTTP/1.1 200 ...
@@ -207,11 +218,7 @@ refresh_trusted_cache_cb(PurpleUtilFetch
   char *header = g_strdup_printf("%s", url_text);
   char *data_loc=NULL;
   const char *hash_id;
-  xmlnode *trusted_hash_root, *start;
-
-  if(!trusted_server_cache_ht){
-    trusted_server_cache_ht = g_hash_table_new(g_str_hash, g_str_equal);
-  }
+  xmlnode *public_server_hash_root, *start;
 
   if(header && strlen(header) >= 14) {
     header += 9;
@@ -223,39 +230,41 @@ refresh_trusted_cache_cb(PurpleUtilFetch
   if(code == 200){
     /* Extract the data to be converted to XML => GList */
     data_loc = strstr(url_text, "\r\n\r\n");
-    trusted_hash_root = xmlnode_from_str(data_loc, -1);
-    if(trusted_hash_root != NULL){
+    public_server_hash_root = xmlnode_from_str(data_loc, -1);
+    if(public_server_hash_root != NULL){
       /* Now load a Hash Table of accepted Hashes, currently they won't
        * contain any data, but this is to keep space for any extra info
        * that the server might give away!
        */
-      start = xmlnode_get_child(trusted_hash_root, "hash");
+      start = xmlnode_get_child(public_server_hash_root, "hash");
       for(;start;start = xmlnode_get_next_twin(start)){
         hash_id = xmlnode_get_attrib(start, "id");
-        g_hash_table_insert(trusted_server_cache_ht, (void *)hash_id, NULL);
+        g_hash_table_insert(public_server_cache_ht, (void *)hash_id, NULL);
       }
-      purple_timeout_add_seconds(TRUSTED_CACHE_REFRESH, refresh_trusted_cache, NULL);
-      /* Load the stats file into a global variable for any updations */
-      root_stats = init_stats();
+      public_server_handle = purple_timeout_add_seconds(PUBLIC_SERVER_CACHE_REFRESH, refresh_public_server_cache, NULL);
+
+      /* Check all account split hashes */
+      refresh_accounts();
+
     }
   } else {
-     purple_timeout_add_seconds(10, refresh_trusted_cache, NULL);
+     public_server_handle = purple_timeout_add_seconds(10, refresh_public_server_cache, NULL);
   }
 }
 
 static gboolean
-refresh_trusted_cache(gpointer data){
+refresh_public_server_cache(gpointer data){
 
   /* Refresh the stored cache of information about IRC/Jabber
    * servers which are in-effect public using md5 hashes!
    */
 
   /* Obtain the list through a webservice */
-  gchar *host, *path, *request, *url= TRUSTED_URL;
+  gchar *host, *path, *request, *url= PUBLIC_SERVER_URL;
   gboolean *send_success;
   int port;
 
-  purple_debug_info("STATS", "requesting trusted ...");
+  purple_debug_info("STATS", "requesting public server ...");
   purple_url_parse(url, &host, &port, &path, NULL, NULL);
   send_success = g_new0(gboolean, 1);
   request = g_strdup_printf(\
@@ -264,7 +273,7 @@ refresh_trusted_cache(gpointer data){
           "Host: %s:%d\r\n\r\n",
           path, host, port);
   purple_debug_info("STATS", "%s", request);
-  purple_util_fetch_url_request(url, TRUE, NULL, FALSE, request, TRUE, refresh_trusted_cache_cb, send_success);
+  purple_util_fetch_url_request(url, TRUE, NULL, FALSE, request, TRUE, refresh_public_server_cache_cb, send_success);
 
   g_free(host);
   g_free(path);
@@ -647,8 +656,6 @@ get_ui_info(){
   GHashTable *ui_info_ht;
   xmlnode *ui_info_xml, *ui_version_xml;
   char *ui_name, *ui_version, *data;
-  GHashTableIter iter;
-  /* gpointer key, value; */
 
   ui_info_ht = purple_core_get_ui_info();
 
@@ -674,16 +681,6 @@ get_ui_info(){
   data = xmlnode_to_str(ui_info_xml, NULL);
   g_hash_table_insert(stats_uis_ht, (void *)ui_name, (void *)data);
 
-  g_hash_table_iter_init(&iter, stats_uis_ht);
-
-  /* purple_debug_info("STATS UI", "starting ui info ... \\n %s: %s", ui_name, data); */
-
-  /* while(g_hash_table_iter_next(&iter, &key, &value)){ */
-
-  /*   purple_debug_info("STATS UI", "%s: %s\\n", (char *)key, (char *)value); */
-
-  /* } */
-
   schedule_stats_save();
 
 
@@ -754,108 +751,85 @@ acc_sign_on_event(PurpleAccount *account
 
   id = get_acc_id(username, protocol);
 
-  /* check if the account already exist in our XML file */
-  if(g_hash_table_lookup(stats_acc_ht, id))
-    purple_debug_info("STATS", "Account already exists!");
-  else{
+  acc = xmlnode_new("account");
 
-    acc = xmlnode_new("account");
+  xmlnode_set_attrib(acc, "id", id);
 
-    xmlnode_set_attrib(acc, "id", id);
+  /* Protocol information */
+  p_node = xmlnode_new_child(acc, "protocol");
+  xmlnode_insert_data(p_node, protocol, -1);
 
-    /* Protocol information */
-    p_node = xmlnode_new_child(acc, "protocol");
-    xmlnode_insert_data(p_node, protocol, -1);
+  /* Number of buddies in account list */
+  len = g_slist_length(purple_find_buddies(account, NULL));
+  len_node = xmlnode_new("buddies");
+  xmlnode_insert_data(len_node, g_strdup_printf("%d", len), -1);
+  xmlnode_insert_child(acc, len_node);
 
-    /* Number of buddies in account list */
-    len = g_slist_length(purple_find_buddies(account, NULL));
-    len_node = xmlnode_new("buddies");
-    xmlnode_insert_data(len_node, g_strdup_printf("%d", len), -1);
-    xmlnode_insert_child(acc, len_node);
+  /* We can also send ``username-splits'' as they will be helpful
+   * in general
+   */
+  username_dup = g_strdup(username);
+  if(user_splits != NULL){
+    for (l = g_list_last(user_splits);l != NULL;l = l->prev) {
+        PurpleAccountUserSplit *split = l->data;
+        const char *value = NULL, *value_md5=NULL;
+        char *c;
+        xmlnode *user_split_node, *user_split_node_hash;
 
-    /* We can also send ``username-splits'' as they will be helpful
-     * in general
-     */
-    username_dup = g_strdup(username);
-
-    if(user_splits != NULL){
-
-      for (l = g_list_last(user_splits);l != NULL;l = l->prev) {
-
-          PurpleAccountUserSplit *split = l->data;
-          const char *value = NULL, *value_md5=NULL;
-          char *c;
-          xmlnode *user_split_node, *user_split_node_hash;
-
-          if(purple_account_user_split_get_reverse(split))
-              c = strrchr(username_dup,
-                      purple_account_user_split_get_separator(split));
-          else
-              c = strchr(username_dup,
-                      purple_account_user_split_get_separator(split));
-
-          if (c != NULL) {
-              *c = '\0';
-              c++;
-              value = c;
-          }
-
-          if (value == NULL){
-              value = "";
-              value_md5 = NULL;
-          } else {
-            value_md5 = md5((const guchar *)value);
-          }
-
-
-          /* Check if the Hash is in the trusted_hash_table */
-          user_split_node = xmlnode_new(g_strdup_printf("%s", split->text));
-          if(g_hash_table_lookup_extended(trusted_server_cache_ht, value_md5, NULL, NULL)){
-            xmlnode_insert_data(user_split_node, value, -1);
-          }
-          xmlnode_insert_child(acc, user_split_node);
-
-          /* Normal MD5 node */
-          user_split_node_hash = xmlnode_new(g_strdup_printf("%s_hash", split->text));
-          xmlnode_insert_data(user_split_node_hash, value_md5, -1);
-          xmlnode_insert_child(acc, user_split_node_hash);
-
-      }
+        if(purple_account_user_split_get_reverse(split))
+            c = strrchr(username_dup,
+                    purple_account_user_split_get_separator(split));
+        else
+            c = strchr(username_dup,
+                    purple_account_user_split_get_separator(split));
+        if (c != NULL) {
+            *c = '\0';
+            c++;
+            value = c;
+        }
+        if (value == NULL){
+            value = "";
+            value_md5 = NULL;
+        } else {
+          value_md5 = md5((const guchar *)value);
+        }
+        /* Check if the Hash is in the public_server_hash_table */
+        user_split_node = xmlnode_new(g_strdup_printf("%s", split->text));
+        if(g_hash_table_lookup_extended(public_server_cache_ht, value_md5, NULL, NULL)){
+          xmlnode_insert_data(user_split_node, value, -1);
+        }
+        xmlnode_insert_child(acc, user_split_node);
+        /* Normal MD5 node */
+        user_split_node_hash = xmlnode_new(g_strdup_printf("%s_hash", split->text));
+        xmlnode_insert_data(user_split_node_hash, value_md5, -1);
+        xmlnode_insert_child(acc, user_split_node_hash);
     }
-
-    /* Server information if Jabber */
-    if(!g_strcmp0(protocol,"prpl-jabber")){
-
-         /* Connect server is helpful in cases when the talk server
-         * is different from domain. Eg, x at mydomain.com could be
-         * registered with google apps and hence use talk.google.com
-         * instead as it's chat server
-         */
-
-        connect_server = purple_account_get_string(account, "connect_server", "");
-        connect_server_node = xmlnode_new("connect-server");
-        xmlnode_insert_data(connect_server_node, connect_server, -1);
-        xmlnode_insert_child(acc, connect_server_node);
-
-



More information about the Commits mailing list