[geary/wip/543-append-failure] Write literal data in chunks when sending to server
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/543-append-failure] Write literal data in chunks when sending to server
- Date: Thu, 29 Aug 2019 13:16:17 +0000 (UTC)
commit e3eef7153c9d3212678d3ed8cfa8fb6043168d56
Author: Michael Gratton <mike vee net>
Date: Thu Aug 29 23:13:48 2019 +1000
Write literal data in chunks when sending to server
By splitting literal writes into apprpriately sized chunks, the
command's response timer can be updated so that the command doesn't
fail due to a timeout as large values are being sent.
Fixes #543
src/engine/imap/command/imap-command.vala | 42 ++++++++++++++++++++++++++++---
1 file changed, 39 insertions(+), 3 deletions(-)
---
diff --git a/src/engine/imap/command/imap-command.vala b/src/engine/imap/command/imap-command.vala
index d4e8a57e..937d78ea 100644
--- a/src/engine/imap/command/imap-command.vala
+++ b/src/engine/imap/command/imap-command.vala
@@ -181,9 +181,45 @@ public class Geary.Imap.Command : BaseObject {
debug("Waiting for continuation");
yield this.literal_spinlock.wait_async(cancellable);
debug("Got continuation");
- yield ser.push_literal_data(
- literal.value.get_uint8_array(), cancellable
- );
+
+ // Buffer size is dependent on timeout, since we
+ // need to ensure we can send a full buffer before
+ // the timeout is up. v.92 56k baud modems have
+ // theoretical max upload of 48kbit/s and GSM 2G
+ // 40kbit/s, but typical is usually well below
+ // that, so assume a low end of 1kbyte/s. Hence
+ // buffer size needs to be less than or equal to
+ // (response_timeout * 1)k, rounded down to the
+ // nearest power of two.
+ uint buf_size = 1;
+ while (buf_size <= this.response_timeout) {
+ buf_size <<= 1;
+ }
+ buf_size >>= 1;
+
+ uint8[] buf = new uint8[buf_size * 1024];
+ GLib.InputStream data = literal.value.get_input_stream();
+ try {
+ while (!data.is_closed()) {
+ size_t read;
+ yield data.read_all_async(
+ buf, Priority.DEFAULT, cancellable, out read
+ );
+ if (read <= 0) {
+ break;
+ }
+
+ buf.length = (int) read;
+ yield ser.push_literal_data(buf, cancellable);
+ this.response_timer.start();
+ }
+ } finally {
+ try {
+ yield data.close_async();
+ } catch (GLib.Error err) {
+ // Oh well
+ }
+ }
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]