WdtOptions.h (95 lines of code) (raw):
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <unistd.h>
#include <wdt/WdtConfig.h>
#include <wdt/util/EncryptionUtils.h>
#include <cstdint>
#include <set>
#include <string>
namespace facebook {
namespace wdt {
struct ThrottlerOptions;
/**
* A singleton class managing different options for WDT.
* There will only be one instance of this class created
* per creation of sender or receiver or both.
* We can now support more than 1 instance of those per process
* and attach a different one to sets of Sender/Receivers.
*/
class WdtOptions {
public:
// WDT option types
static const char* FLASH_OPTION_TYPE;
static const char* DISK_OPTION_TYPE;
/**
* A static method that can be called to create
* the singleton copy of WdtOptions through the lifetime
* of wdt run.
* This is to be avoided, instead use the WdtOptions instance
* off each object.
* @deprecated
*/
static const WdtOptions& get();
/**
* Method to get mutable copy of the singleton.
* This is to be avoided, instead use the WdtOptions instance
* off each object.
* @deprecated
*/
static WdtOptions& getMutable();
/**
* Modifies options based on the type specified
*
* @param optionType option type
* @param userSpecifiedOptions options specified by user, this options are not
* changed
*/
void modifyOptions(const std::string& optionType,
const std::set<std::string>& userSpecifiedOptions);
/**
* Use ipv6 while establishing connection.
* When both ipv6 and ipv4 are false we will try both
* if the host name has both.
*/
bool ipv6{false};
/**
* Use ipv4, this takes precedence over ipv6
*/
bool ipv4{false};
/**
* DSCP flag, see https://en.wikipedia.org/wiki/Differentiated_services.
*/
int dscp{0};
/**
* Run wdt in a mode where the receiver doesn't
* write anything to the disk
*/
bool skip_writes{false};
/**
* Continue the operation even if there are
* socket errors
*/
bool ignore_open_errors{false};
/**
* Run the sender in two phases. First phase is
* discovery phase and the second one is sending
* the files over wire.
*/
bool two_phases{false};
/**
* This option specifies whether wdt should
* discover symlinks and transfer those files
*/
bool follow_symlinks{false};
/**
* Starting start_port for wdt. Number of ports allocated
* are contiguous sequence starting of numSockets
* starting from this start_port
*/
int32_t start_port{22356}; // W (D) T = 0x5754
int32_t num_ports{8};
/**
* If true, will use start_port otherwise will use 0 / dynamic ports
*/
bool static_ports{false};
/**
* Maximum buffer size for the write on the sender
* as well as while reading on receiver.
*/
int32_t buffer_size{256 * 1024};
/**
* Maximum number of retries for the sender in case of
* failures before exiting
*/
int32_t max_retries{20};
/**
* Time in ms to sleep before retrying after each connection
* failure
*/
int32_t sleep_millis{50};
/**
* Specify the backlog to start the server socket with. Look
* into ServerSocket.h
*/
int32_t backlog{1};
/**
* Rate at which we would like data to be transferred,
* specifying this as < 0 makes it unlimited
*/
double avg_mbytes_per_sec{-1};
/**
* Rate at which tokens will be generated in TB algorithm.
* When we lag behind, this will allow us to go faster,
* specify as < 0 to make it unlimited. Specify as 0
* for auto configuring.
* auto conf as (kPeakMultiplier * avgMbytesPerSec_)
* Find details in Sender.cpp
*/
double max_mbytes_per_sec{0};
/**
* Maximum bucket size of TB algorithm in mbytes
* This together with maxBytesPerSec_ will
* make for maximum burst rate. If specified as 0 it is
* auto configured in Sender.cpp
*/
double throttler_bucket_limit{0};
/**
* Throttler logs statistics like average and max rate.
* This option specifies on how frequently should those
* be logged
*/
int64_t throttler_log_time_millis{0};
/**
* Regex for the files to be included in discovery
*/
std::string include_regex{""};
/**
* Regex for the files to be excluded from the discovery
*/
std::string exclude_regex{""};
/**
* Regex for the directories that shouldn't be explored
*/
std::string prune_dir_regex{""};
/**
* Maximum number of times sender thread reconnects without making any
* progress
*/
int max_transfer_retries{3};
/**
* True if full reporting is enabled. False otherwise
*/
bool full_reporting{false};
/**
* IntervalMillis(in milliseconds) between progress reports
*/
int progress_report_interval_millis{
isatty(STDOUT_FILENO) ? 20 : 200}; // default value is much higher for
// logging case, this is done to avoid
// flooding the log with progress
// information
/**
* block size, it is used to break bigger files into smaller chunks
* block_size of <= 0 disables block transfer
*/
double block_size_mbytes{16};
/**
* timeout in accept call at the server
*/
int32_t accept_timeout_millis{100};
/**
* maximum number of retries for accept call in joinable mode. we try to
* accept with timeout of accept_timeout_millis. first connection from sender
* must come before max_accept_retries.
*/
int32_t max_accept_retries{500};
/**
* accept window size in millis. For a session, after the first connection is
* received, other connections must be received before this duration.
*/
int32_t accept_window_millis{2000};
/**
* timeout for socket read
*/
int read_timeout_millis{5000};
/**
* timeout for socket write
*/
int write_timeout_millis{5000};
/**
* timeout for socket connect
*/
int32_t connect_timeout_millis{1000};
/**
* interval in ms between abort checks
*/
int abort_check_interval_millis{200};
/**
* Disk sync interval in mb. A negative value disables syncing
*/
double disk_sync_interval_mb{0.5};
/**
* If true, each file is fsync'ed after its last block is
* received.
* Note that this can cause some performance hit on some filesystems, however
* if you disable it there no correctness guarantee will be provided.
*/
bool fsync{true};
/**
* Intervals in millis after which progress reporter updates current
* throughput
*/
int throughput_update_interval_millis{500};
/**
* Flag for turning on/off checksum. Redundant gcm in ENC_AES128_GCM.
*/
bool enable_checksum{false};
/**
* If true, perf stats are collected and reported at the end of transfer
*/
bool enable_perf_stat_collection{false};
/**
* Interval in milliseconds after which transfer log is written to disk
*/
int transfer_log_write_interval_ms{100};
/**
* If true, compact transfer log if transfer finishes successfully
*/
bool enable_transfer_log_compaction{false};
/**
* If true, download resumption is enabled
*/
bool enable_download_resumption{false};
/**
* At transfer end, do not delete transfer log
*/
bool keep_transfer_log{true};
/**
* If true, WDT does not verify sender ip during resumption
*/
bool disable_sender_verification_during_resumption{false};
/**
* Max number of senders allowed globally
*/
int global_sender_limit{0};
/**
* Max number of receivers allowed globally
*/
int global_receiver_limit{0};
/**
* Max number of senders allowed per namespace
*/
int namespace_sender_limit{0};
/**
* Max number of receivers allowed per namespace
*/
int namespace_receiver_limit{1};
/**
* Read files in O_DIRECT
*/
bool odirect_reads{false};
/**
* If true, files are not pre-allocated using posix_fallocate.
* This flag should not be used directly by wdt code. It should be accessed
* through shouldPreallocateFiles method.
*/
bool disable_preallocation{false};
/**
* If true, destination directory tree is trusted during resumption. So, only
* the remaining portion of the files are transferred. This is only supported
* if preallocation and block mode is disabled.
*/
bool resume_using_dir_tree{false};
/**
* If > 0 will open up to that number of files during discovery
* if 0 will not open any file during discovery
* if < 0 will try to open all the files during discovery (which may fail
* with too many open files errors)
*/
int open_files_during_discovery{0};
/**
* If true, wdt can overwrite existing files
*/
bool overwrite{false};
/**
* Extra time buffer to account for network when sender waits for receiver to
* finish processing buffered data
*/
int drain_extra_ms{500};
/**
* Encryption type to use
*/
std::string encryption_type{encryptionTypeToStr(ENC_AES128_GCM)};
/**
* Encryption tag verification interval in bytes. A value of zero disables
* incremental tag verification. In that case, tag only gets verified at the
* end.
*/
int encryption_tag_interval_bytes{4 * 1024 * 1024};
/**
* send buffer size for Sender. If < = 0, buffer size is not set
*/
int send_buffer_size{0};
/**
* receive buffer size for Receiver. If < = 0, buffer size is not set
*/
int receive_buffer_size{0};
/**
* If true, extra files on the receiver side is deleted during resumption
*/
bool delete_extra_files{false};
/**
* If true, fadvise is skipped after block write
*/
bool skip_fadvise{false};
/**
* If true, periodic heart-beats from receiver to sender is enabled.
* The heart-beat interval is determined by the socket read timeout of the
* sender.
* WDT senders streams data and only waits for a receiver response after
* all the blocks are sent. Because of the high socket buffer sizes, it might
* take a long time for receiver to process all the bytes sent. So, for slower
* threads, there is significant difference between the time receiver
* processes all the bytes and the time sender finishes sending all the bytes.
* So, the sender might time out while waiting for the response from receiver.
* This happens a lot more for disks because of the lower io throughput.
* To solve this, receiver sends heart-beats to signal that it is sill
* processing data, and sender waits will it is still getting heart-beats.
*/
bool enable_heart_beat{true};
/**
* Number of MBytes after which encryption iv is changed. A value of 0
* disables iv change.
*/
int iv_change_interval_mb{32 * 1024};
/**
* Set O_CLOEXEC flag when open files.
*/
bool close_on_exec{false};
/**
* @return whether files should be pre-allocated or not
*/
bool shouldPreallocateFiles() const;
/**
* @return whether transfer log based resumption is enabled
*/
bool isLogBasedResumption() const;
/**
* @return whether directory tree based resumption is enabled
*/
bool isDirectoryTreeBasedResumption() const;
/**
* @return throttler options
*/
ThrottlerOptions getThrottlerOptions() const;
// NOTE: any option added here should also be added to util/WdtFlags.cpp.inc
/**
* Initialize the fields of this object from another src one. ie makes 1 copy
* explicitly.
*/
void copyInto(const WdtOptions& src);
/**
* This used to be a singleton (which as always is a pretty bad idea)
* so copy constructor and assignment operator were deleted
* We still want to avoid accidental copying around of a fairly
* big object thus the copyInto pattern above
*/
WdtOptions(const WdtOptions&) = delete;
WdtOptions() {
}
~WdtOptions() {
}
private:
WdtOptions& operator=(const WdtOptions&) = default;
};
} // namespace wdt
} // namespace facebook