Improve writing to state file and clean up repository

Instead of using a timer, schedule writes on each new messages. This ensures that there are not too many writes on big updates and still works without a long-running timer.
This commit is contained in:
mjentsch 2015-01-23 16:37:22 +01:00
parent 1dd7be0262
commit 51bb79947c
5 changed files with 63 additions and 55 deletions

View file

@ -106,6 +106,23 @@ void write_state_file (struct tgl_state *TLS) {
close (state_file_fd);
}
static gboolean write_state_file_gw (gpointer data) {
struct tgl_state *TLS = data;
((connection_data *)TLS->ev_base)->write_timer = 0;
write_state_file ((struct tgl_state *)TLS);
return FALSE;
}
void write_state_file_schedule (struct tgl_state *TLS) {
connection_data *conn = TLS->ev_base;
if (! conn->write_timer) {
conn->write_timer = purple_timeout_add (0, write_state_file_gw, TLS);
}
}
void write_dc (struct tgl_dc *DC, void *extra) {
int auth_file_fd = *(int *)extra;
if (!DC) {

View file

@ -26,6 +26,7 @@ void read_state_file (struct tgl_state *TLS);
void read_auth_file (struct tgl_state *TLS);
void write_auth_file (struct tgl_state *TLS);
void write_state_file (struct tgl_state *TLS);
void write_state_file_schedule (struct tgl_state *TLS);
void read_secret_chat_file (struct tgl_state *TLS);
void write_secret_chat_file (struct tgl_state *TLS);

View file

@ -291,17 +291,6 @@ static tgl_peer_t *find_peer_by_name (struct tgl_state *TLS, const char *who) {
return NULL;
}
static gboolean queries_timerfunc (gpointer data) {
debug ("queries_timerfunc()\n");
connection_data *conn = data;
if (conn->updated) {
conn->updated = 0;
write_state_file (conn->TLS);
}
return 1;
}
static void start_secret_chat (PurpleBlistNode *node, gpointer data) {
PurpleBuddy *buddy = data;
connection_data *conn = purple_connection_get_protocol_data (
@ -347,43 +336,43 @@ struct tgl_update_callback tgp_callback = {
};
void on_message_load_photo (struct tgl_state *TLS, void *extra, int success, char *filename) {
connection_data *conn = TLS->ev_base;
gchar *data = NULL;
size_t len;
GError *err = NULL;
g_file_get_contents (filename, &data, &len, &err);
int imgStoreId = purple_imgstore_add_with_id (g_memdup(data, (guint)len), len, NULL);
used_images_add (conn, imgStoreId);
char *image = format_img_full (imgStoreId);
struct tgl_message *M = extra;
switch (tgl_get_peer_type (M->to_id)) {
case TGL_PEER_CHAT:
if (!our_msg(TLS, M)) {
chat_add_message (TLS, M, image);
}
break;
case TGL_PEER_USER:
if (out_msg(TLS, M)) {
p2tgl_got_im (TLS, M->to_id, image, PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_IMAGES, M->date);
} else {
p2tgl_got_im (TLS, M->from_id, image, PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, M->date);
}
break;
int imgStoreId = p2tgl_imgstore_add_with_id (filename);
if (imgStoreId > 0) {
used_images_add (conn, imgStoreId);
char *image = format_img_full (imgStoreId);
struct tgl_message *M = extra;
switch (tgl_get_peer_type (M->to_id)) {
case TGL_PEER_CHAT:
if (!our_msg (TLS, M)) {
chat_add_message (TLS, M, image);
}
break;
case TGL_PEER_USER:
if (out_msg (TLS, M)) {
p2tgl_got_im (TLS, M->to_id, image, PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_IMAGES, M->date);
} else {
p2tgl_got_im (TLS, M->from_id, image, PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, M->date);
}
break;
}
g_free (image);
}
g_free (image);
conn = TLS->ev_base;
conn->updated = 1;
}
static void update_message_received (struct tgl_state *TLS, struct tgl_message *M) {
debug ("received message\n");
connection_data *conn = TLS->ev_base;
conn->updated = 1;
/* don't write to this file on every single message, which
can be pretty overkill on calls to tgl_do_get_difference that result in many
updates */
write_state_file_schedule (conn->TLS);
if (M->service) {
char *text = format_service_msg (TLS, M);
if (text) {
@ -398,11 +387,15 @@ static void update_message_received (struct tgl_state *TLS, struct tgl_message *
}
g_free (text);
}
conn->updated = 1;
return;
}
if ((M->flags & (FLAG_MESSAGE_EMPTY | FLAG_DELETED)) || !(M->flags & FLAG_CREATED)) {
if (
(M->flags & (FLAG_MESSAGE_EMPTY | FLAG_DELETED)) ||
!(M->flags & FLAG_CREATED) ||
!M->message ||
our_msg (TLS, M) // Message sent in this application, already added to history
) {
return;
}
if (!tgl_get_peer_type (M->to_id)) {
@ -415,10 +408,6 @@ static void update_message_received (struct tgl_state *TLS, struct tgl_message *
return;
}
if (!M->message || our_msg(TLS, M)) {
return;
}
char *text = format_message(M);
switch (tgl_get_peer_type (M->to_id)) {
case TGL_PEER_CHAT:
@ -436,8 +425,9 @@ static void update_message_received (struct tgl_state *TLS, struct tgl_message *
case TGL_PEER_USER:
// :TODO: figure out how to add messages from different devices to history
if (out_msg(TLS, M)) {
// Outgoing message sent from a different device
// :TODO: figure out how to add messages from different devices to history
p2tgl_got_im (TLS, M->to_id, text, PURPLE_MESSAGE_SEND, M->date);
} else {
p2tgl_got_im (TLS, M->from_id, text, PURPLE_MESSAGE_RECV, M->date);
@ -701,8 +691,6 @@ void on_ready (struct tgl_state *TLS) {
tgl_do_get_difference (TLS, 0, 0, 0);
tgl_do_get_dialog_list (TLS, 0, 0);
tgl_do_update_contact_list (TLS, 0, 0);
conn->timer = purple_timeout_add (5000, queries_timerfunc, conn);
}
static const char *tgprpl_list_icon (PurpleAccount * acct, PurpleBuddy * buddy) {
@ -826,7 +814,7 @@ static void tgprpl_login (PurpleAccount * acct) {
static void tgprpl_close (PurpleConnection * gc) {
debug ("tgprpl_close()\n");
connection_data *conn = purple_connection_get_protocol_data (gc);
purple_timeout_remove (conn->timer);
connection_data_free (conn);
}

View file

@ -111,14 +111,16 @@ connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *
void *connection_data_free (connection_data *conn)
{
purple_timeout_remove (conn->timer);
if (conn->login_timer) { purple_timeout_remove(conn->login_timer); }
if (conn->write_timer) { purple_timeout_remove (conn->write_timer); }
if (conn->login_timer) { purple_timeout_remove (conn->login_timer); }
tgp_g_queue_free_full (conn->pending_reads, pending_reads_free_cb);
tgp_g_queue_free_full (conn->new_messages, message_text_free);
g_hash_table_destroy (conn->joining_chats);
g_list_free_full (conn->used_images, used_image_free);
tgl_free_all (conn->TLS);
free (conn->TLS);
free (conn);
return NULL;
}

View file

@ -36,7 +36,7 @@ typedef struct {
GQueue *pending_reads;
GList *used_images;
GHashTable *joining_chats;
guint timer;
guint write_timer;
guint login_timer;
int in_fallback_chat;
} connection_data;