pidgin: 94615bf7: To decrease the odds of hitting the rate...
evands at pidgin.im
evands at pidgin.im
Sun Jul 20 21:25:46 EDT 2008
-----------------------------------------------------------------
Revision: 94615bf7b3bc4cd6c88bc68018c49286a1058e93
Ancestor: 12b9c02788253d50b8dbabc5e2c9c42c9ae2bd7e
Author: evands at pidgin.im
Date: 2008-07-20T22:19:10
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/94615bf7b3bc4cd6c88bc68018c49286a1058e93
Modified files:
libpurple/protocols/oscar/oscar.c
libpurple/protocols/oscar/oscar.h
libpurple/protocols/oscar/oscar_data.c
ChangeLog:
To decrease the odds of hitting the rate limit ceiling rapidly on a
buddy list with a large number of ICQ buddies, space out our requests
for the ICQ Status Note. This has 2 beneficial effects:
1. Request notes over a longer period of time, avoiding hitting the rate
limit immediately.
2. Coalesce multiple requests for the same note into a single request.
Previously, we were making n*2 to n*4 requests, where n is the number
of ICQ contacts with status notes, at signon, as purple_parse_oncoming
is called multiple times for each one.
-------------- next part --------------
============================================================
--- libpurple/protocols/oscar/oscar.c 5f76ec30a2890b09fcf695e155ec2cedef352c7a
+++ libpurple/protocols/oscar/oscar.c 86e602ade22c718ed23452fde421fb71d7efb4f9
@@ -1893,6 +1893,39 @@ purple_handle_redirect(OscarData *od, Fl
return 1;
}
+static gboolean purple_requesticqstatusnote(gpointer data)
+{
+ PurpleConnection *gc = data;
+ OscarData *od = gc->proto_data;
+ char *sn;
+ struct aim_ssi_item *ssi_item;
+ aim_tlv_t *note_hash;
+
+ if (!od->statusnotes_queue) {
+ purple_debug_misc("oscar", "No more ICQ status notes to request");
+ od->statusnotes_queue_timer = 0;
+ return FALSE;
+ }
+
+ sn = od->statusnotes_queue->data;
+
+ ssi_item = aim_ssi_itemlist_finditem(od->ssi.local,
+ NULL, sn, AIM_SSI_TYPE_BUDDY);
+ if (ssi_item != NULL)
+ {
+ note_hash = aim_tlv_gettlv(ssi_item->data, 0x015c, 1);
+ if (note_hash != NULL) {
+ aim_icq_getstatusnote(od, sn, note_hash->value, note_hash->length);
+ }
+ }
+
+ od->statusnotes_queue = g_slist_remove(od->statusnotes_queue, sn);
+ free(sn);
+
+ return TRUE;
+}
+
+
static int purple_parse_oncoming(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
{
PurpleConnection *gc;
@@ -2074,8 +2107,20 @@ static int purple_parse_oncoming(OscarDa
if (ssi_item != NULL)
{
note_hash = aim_tlv_gettlv(ssi_item->data, 0x015c, 1);
- if (note_hash != NULL)
- aim_icq_getstatusnote(od, info->sn, note_hash->value, note_hash->length);
+ if (note_hash != NULL) {
+ /* We do automatic rate limiting, so a flood of requests would not disconnect us.
+ * However, they would mean that we had to wait a potentially long time to be able to message
+ * in real time again. Also, since we're requesting with every purple_parse_oncoming() call,
+ * which often come in groups, we should coalesce to do a single lookup.
+ */
+ if (!od->statusnotes_queue || (g_slist_find_custom(od->statusnotes_queue, info->sn, (GCompareFunc)strcmp) == NULL)) {
+ od->statusnotes_queue = g_slist_append(od->statusnotes_queue, g_strdup(info->sn));
+
+ if (od->statusnotes_queue_timer)
+ purple_timeout_remove(od->statusnotes_queue_timer);
+ od->statusnotes_queue_timer = purple_timeout_add_seconds(2, purple_requesticqstatusnote, gc);
+ }
+ }
}
}
============================================================
--- libpurple/protocols/oscar/oscar.h f45b3ed6f71c21ae20838f95c3b7515f61948fb1
+++ libpurple/protocols/oscar/oscar.h 575cd89b55f8e749efc13364e42409062262f440
@@ -544,6 +544,10 @@ struct _OscarData
/** A linked list containing PeerConnections. */
GSList *peer_connections;
+
+ /** Queue of ICQ Status Notes to request. */
+ GSList *statusnotes_queue;
+ gint statusnotes_queue_timer;
};
/* Valid for calling aim_icq_setstatus() and for aim_userinfo_t->icqinfo.status */
============================================================
--- libpurple/protocols/oscar/oscar_data.c 1d9f9c76fefec415a27c847474d28fd9887fa1f9
+++ libpurple/protocols/oscar/oscar_data.c 83016ef790171eb6d56d1c6ed803ee38bde2c64e
@@ -92,6 +92,14 @@ oscar_data_destroy(OscarData *od)
od->requesticon = g_slist_remove(od->requesticon, sn);
g_free(sn);
}
+ while (od->statusnotes_queue)
+ {
+ gchar *sn = od->statusnotes_queue->data;
+ od->statusnotes_queue = g_slist_remove(od->statusnotes_queue, sn);
+ g_free(sn);
+ }
+ if (od->statusnotes_queue_timer)
+ purple_timeout_remove(od->statusnotes_queue_timer);
g_free(od->email);
g_free(od->newp);
g_free(od->oldp);
More information about the Commits
mailing list