1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::num::{NonZeroU16, NonZeroU32};
use std::time::Duration;

/// Options when creating [`super::Sftp`].
#[derive(Debug, Copy, Clone, Default)]
pub struct SftpOptions {
    flush_interval: Option<Duration>,
    max_read_len: Option<NonZeroU32>,
    max_write_len: Option<NonZeroU32>,
    max_pending_requests: Option<NonZeroU16>,
    max_buffered_write: Option<NonZeroU32>,
}

impl SftpOptions {
    /// Create a new [`SftpOptions`].
    pub const fn new() -> Self {
        Self {
            flush_interval: None,
            max_read_len: None,
            max_write_len: None,
            max_pending_requests: None,
            max_buffered_write: None,
        }
    }

    /// Set `flush_interval`, default value is 0.5 ms.
    ///
    /// `flush_interval` decides the maximum time your requests would stay
    /// in the write buffer before it is actually sent to the remote.
    ///
    /// If another thread is doing flushing, then the internal `flush_task`
    /// [`super::Sftp`] started would wait for another `flush_interval`.
    ///
    /// Setting it to be larger might improve overall performance by grouping
    /// writes and reducing the overhead of packet sent over network, but it
    /// might also increase latency, so be careful when setting the
    /// `flush_interval`.
    ///
    /// If `flush_interval` is set to 0, then every packet
    /// is flushed immediately.
    ///
    /// NOTE that it is perfectly OK to set `flush_interval` to 0 and
    /// it would not slowdown the program, as flushing is only performed
    /// on daemon.
    #[must_use]
    pub const fn flush_interval(mut self, flush_interval: Duration) -> Self {
        self.flush_interval = Some(flush_interval);
        self
    }

    pub(super) fn get_flush_interval(&self) -> Duration {
        self.flush_interval
            .unwrap_or_else(|| Duration::from_micros(500))
    }

    /// Set `max_read_len`.
    ///
    /// It can be used to reduce `max_read_len`, but cannot be used
    /// to increase `max_read_len`.
    #[must_use]
    pub const fn max_read_len(mut self, max_read_len: NonZeroU32) -> Self {
        self.max_read_len = Some(max_read_len);
        self
    }

    pub(super) fn get_max_read_len(&self) -> Option<u32> {
        self.max_read_len.map(NonZeroU32::get)
    }

    /// Set `max_write_len`.
    ///
    /// It can be used to reduce `max_write_len`, but cannot be used
    /// to increase `max_write_len`.
    #[must_use]
    pub const fn max_write_len(mut self, max_write_len: NonZeroU32) -> Self {
        self.max_write_len = Some(max_write_len);
        self
    }

    pub(super) fn get_max_write_len(&self) -> Option<u32> {
        self.max_write_len.map(NonZeroU32::get)
    }

    /// Set `max_pending_requests`.
    ///
    /// If the pending_requests is larger than max_pending_requests, then the
    /// flush task will flush the write buffer without waiting for `flush_interval`.
    ///
    /// It is set to 100 by default.
    #[must_use]
    pub const fn max_pending_requests(mut self, max_pending_requests: NonZeroU16) -> Self {
        self.max_pending_requests = Some(max_pending_requests);
        self
    }

    pub(super) fn get_max_pending_requests(&self) -> u16 {
        self.max_pending_requests
            .map(NonZeroU16::get)
            .unwrap_or(100)
    }

    /// Set `max_buffered_write`.
    ///
    /// It decides when [`crate::highlevel::File`] and
    /// [`crate::highlevel::TokioCompactFile`] switch to directly write to the
    /// buffer in an atomic manner.
    /// NOTE that this would limit the maximum write to
    /// [`crate::highlevel::max_atomic_write_len`] bytes.
    /// bytes.
    ///
    /// value greater or equal to [`crate::highlevel::max_atomic_write_len`].
    /// value greater or equal to [`crate::highlevel::max_atomic_write_len`].
    ///
    /// It is set to `200` by default.
    #[must_use]
    pub const fn max_buffered_write(mut self, max_buffered_write: NonZeroU32) -> Self {
        self.max_buffered_write = Some(max_buffered_write);
        self
    }

    pub(super) fn get_max_buffered_write(&self) -> u32 {
        self.max_buffered_write.map(NonZeroU32::get).unwrap_or(200)
    }
}