From: Art Cancro Date: Mon, 8 Mar 2021 04:07:08 +0000 (-0500) Subject: When exporting a message, write to the client 10 KB at a time. X-Git-Tag: v939~88 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=79d6eafd2a8bb379b3e13ff071a000d9bf36771b When exporting a message, write to the client 10 KB at a time. --- diff --git a/citadel/modules/migrate/serv_migrate.c b/citadel/modules/migrate/serv_migrate.c index e2e2ee1cf..7cc8fc041 100644 --- a/citadel/modules/migrate/serv_migrate.c +++ b/citadel/modules/migrate/serv_migrate.c @@ -309,12 +309,14 @@ void migr_export_message(long msgnum) { struct MetaData smi; struct CtdlMessage *msg; struct ser_ret smr; + long bytes_written = 0; + long this_block = 0; + + // We can use a static buffer here because there will never be more than + // one of this operation happening at any given time, and it's really best + // to just keep it allocated once instead of torturing malloc/free. + // Call this function with msgnum "-1" to free the buffer when finished. - /* We can use a static buffer here because there will never be more than - * one of this operation happening at any given time, and it's really best - * to just keep it allocated once instead of torturing malloc/free. - * Call this function with msgnum "-1" to free the buffer when finished. - */ static int encoded_alloc = 0; static char *encoded_msg = NULL; @@ -327,10 +329,10 @@ void migr_export_message(long msgnum) { return; } - /* Ok, here we go ... */ + // Ok, here we go ... msg = CtdlFetchMessage(msgnum, 1); - if (msg == NULL) return; /* fail silently */ + if (msg == NULL) return; // fail silently client_write(HKEY("\n")); GetMetaData(&smi, msgnum); @@ -343,7 +345,7 @@ void migr_export_message(long msgnum) { CtdlSerializeMessage(&smr, msg); CM_Free(msg); - /* Predict the buffer size we need. Expand the buffer if necessary. */ + // Predict the buffer size we need. Expand the buffer if necessary. int encoded_len = smr.len * 15 / 10 ; if (encoded_len > encoded_alloc) { encoded_alloc = encoded_len; @@ -351,13 +353,24 @@ void migr_export_message(long msgnum) { } if (encoded_msg == NULL) { - /* Questionable hack that hopes it'll work next time and we only lose one message */ + // Questionable hack that hopes it'll work next time and we only lose one message encoded_alloc = 0; } else { - /* Once we do the encoding we know the exact size */ + // Once we do the encoding we know the exact size encoded_len = CtdlEncodeBase64(encoded_msg, (char *)smr.ser, smr.len, 1); - client_write(encoded_msg, encoded_len); + + // Careful now. If the message is gargantuan, trying to write multiple gigamegs in one + // big write operation can make our transport unhappy. So we'll chunk it up 10 KB at a time. + bytes_written = 0; + while ( (bytes_written < encoded_len) && (!server_shutting_down) ) { + this_block = encoded_len - bytes_written; + if (this_block > 10240) { + this_block = 10240; + } + client_write(&encoded_msg[bytes_written], this_block); + bytes_written += this_block; + } } free(smr.ser); diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 39bc7703a..081be8980 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -2556,7 +2556,7 @@ long send_message(struct CtdlMessage *msg) { /* - * Serialize a struct CtdlMessage into the format used on disk and network. + * Serialize a struct CtdlMessage into the format used on disk. * * This function loads up a "struct ser_ret" (defined in server.h) which * contains the length of the serialized message and a pointer to the