Skip to content

Commit cfb6100

Browse files
authored
add a default file streaming options (#566)
1 parent 7ef70e2 commit cfb6100

File tree

12 files changed

+35
-7
lines changed

12 files changed

+35
-7
lines changed

include/aws/s3/private/s3_client_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ struct aws_s3_client {
239239
const uint64_t max_part_size;
240240

241241
/* File I/O options. */
242+
bool fio_options_set;
242243
struct aws_s3_file_io_options fio_opts;
243244

244245
/* The size threshold in bytes for when to use multipart uploads for a AWS_S3_META_REQUEST_TYPE_PUT_OBJECT meta

include/aws/s3/private/s3_meta_request_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ int aws_s3_meta_request_init_base(
310310
struct aws_s3_client *client,
311311
size_t part_size,
312312
bool should_compute_content_md5,
313+
bool should_default_streaming,
313314
const struct aws_s3_meta_request_options *options,
314315
void *impl,
315316
struct aws_s3_meta_request_vtable *vtable,

include/aws/s3/private/s3_util.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
#endif
2525
#define KB_TO_BYTES(kb) ((kb) * 1024)
2626
#define MB_TO_BYTES(mb) ((mb) * 1024 * 1024)
27-
#define GB_TO_BYTES(gb) ((gb) * 1024 * 1024 * 1024ULL)
27+
#define GB_TO_BYTES(gb) ((uint64_t)(gb) * 1024 * 1024 * 1024ULL)
28+
#define TB_TO_BYTES(tb) ((uint64_t)(tb) * 1024 * 1024 * 1024 * 1024ULL)
2829

2930
#define MS_TO_NS(ms) ((uint64_t)(ms) * 1000000)
3031
#define SEC_TO_NS(ms) ((uint64_t)(ms) * 1000000000)
@@ -154,6 +155,11 @@ AWS_S3_API
154155
/* TODO: now this is hard-coded as 8MB, but maybe something else is better. */
155156
extern const size_t g_streaming_buffer_size;
156157

158+
AWS_S3_API
159+
extern const double g_default_throughput_target_gbps;
160+
161+
AWS_S3_API
162+
extern const uint64_t g_streaming_object_size_threshold;
157163
/**
158164
* Returns AWS_S3_REQUEST_TYPE_UNKNOWN if name doesn't map to an enum value.
159165
*/

include/aws/s3/s3_client.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ struct aws_s3_file_io_options {
321321
* Skip buffering the part in memory before sending the request.
322322
* If set, set the `disk_throughput_gbps` to be reasonable align with the available disk throughput.
323323
* Otherwise, the transfer may fail with connection starvation.
324+
*
324325
* Default to false.
325326
**/
326327
bool should_stream;
@@ -333,6 +334,8 @@ struct aws_s3_file_io_options {
333334
* Notes: There are possibilities that cannot reach the all available disk throughput:
334335
* 1. Disk is busy with other applications
335336
* 2. OS Cache may cap the throughput, use `direct_io` to get around this.
337+
*
338+
* Note: When `streaming_upload` is true, this default to 10 Gbps.
336339
**/
337340
double disk_throughput_gbps;
338341

@@ -475,7 +478,7 @@ struct aws_s3_client_config {
475478
* Optional.
476479
* If set, this controls how the client interact with file I/O.
477480
* Read `aws_s3_file_io_options` for details.
478-
* Notes: Only applies when AWS_S3_META_REQUEST_TYPE_PUT_OBJECT is set.
481+
* Notes: Only applies to meta requests with `send_filepath` set.
479482
* TODO: adapt it to `recv_filepath`.
480483
*
481484
* eg:
@@ -821,6 +824,9 @@ struct aws_s3_meta_request_options {
821824
* Notes: Only applies when `send_filepath` is set.
822825
* TODO: adapt it to `recv_filepath`.
823826
*
827+
* Note: if both client and meta request don't set this, for objects larger than 2TiB, this will be set to a default
828+
* options with `should_stream` to be True and others follow the default to avoid memory issues.
829+
*
824830
* eg:
825831
* - When the file is too large to fit in the buffer, set `should_stream` to avoid buffering the whole parts in
826832
* memory.

source/s3_auto_ranged_get.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct aws_s3_meta_request *aws_s3_meta_request_auto_ranged_get_new(
7777
client,
7878
part_size,
7979
false,
80+
false,
8081
options,
8182
auto_ranged_get,
8283
&s_s3_auto_ranged_get_vtable,

source/s3_auto_ranged_put.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ struct aws_s3_meta_request *aws_s3_meta_request_auto_ranged_put_new(
352352
part_size,
353353
client->compute_content_md5 == AWS_MR_CONTENT_MD5_ENABLED ||
354354
aws_http_headers_has(aws_http_message_get_headers(options->message), g_content_md5_header_name),
355+
content_length > g_streaming_object_size_threshold,
355356
options,
356357
auto_ranged_put,
357358
&s_s3_auto_ranged_put_vtable,

source/s3_client.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ const uint32_t g_max_num_connections = 10000;
7979
*/
8080
static const size_t s_default_part_size = 8 * 1024 * 1024;
8181
static const uint64_t s_default_max_part_size = 5368709120ULL;
82-
static const double s_default_throughput_target_gbps = 10.0;
8382
static const uint32_t s_default_max_retries = 5;
8483
static size_t s_dns_host_address_ttl_seconds = 5 * 60;
8584

@@ -386,6 +385,7 @@ struct aws_s3_client *aws_s3_client_new(
386385

387386
if (client_config->fio_opts) {
388387
client->fio_opts = *client_config->fio_opts;
388+
client->fio_options_set = true;
389389
}
390390

391391
struct aws_s3_buffer_pool_config buffer_pool_config = {
@@ -590,7 +590,7 @@ struct aws_s3_client *aws_s3_client_new(
590590
if (client_config->throughput_target_gbps > 0.0) {
591591
*((double *)&client->throughput_target_gbps) = client_config->throughput_target_gbps;
592592
} else {
593-
*((double *)&client->throughput_target_gbps) = s_default_throughput_target_gbps;
593+
*((double *)&client->throughput_target_gbps) = g_default_throughput_target_gbps;
594594
}
595595

596596
*((enum aws_s3_meta_request_compute_content_md5 *)&client->compute_content_md5) =
@@ -1206,7 +1206,6 @@ static struct aws_s3_meta_request *s_s3_client_meta_request_factory_default(
12061206
"Could not create meta request."
12071207
"the send file path %s is invalid",
12081208
aws_string_c_str(file_path));
1209-
aws_raise_error(AWS_ERROR_FILE_INVALID_PATH);
12101209
} else if (aws_file_get_length(file, (int64_t *)&content_length)) {
12111210
AWS_LOGF_ERROR(
12121211
AWS_LS_S3_META_REQUEST,

source/s3_copy_object.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct aws_s3_meta_request *aws_s3_meta_request_copy_object_new(
7979
client,
8080
UNKNOWN_PART_SIZE,
8181
false,
82+
false,
8283
options,
8384
copy_object,
8485
&s_s3_copy_object_vtable,

source/s3_default_meta_request.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct aws_s3_meta_request *aws_s3_meta_request_default_new(
9292
client,
9393
0,
9494
should_compute_content_md5,
95+
false,
9596
options,
9697
meta_request_default,
9798
&s_s3_meta_request_default_vtable,

source/s3_meta_request.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ int aws_s3_meta_request_init_base(
157157
struct aws_s3_client *client,
158158
size_t part_size,
159159
bool should_compute_content_md5,
160+
bool should_default_streaming,
160161
const struct aws_s3_meta_request_options *options,
161162
void *impl,
162163
struct aws_s3_meta_request_vtable *vtable,
@@ -184,8 +185,16 @@ int aws_s3_meta_request_init_base(
184185
/* Deep copy the file io options. */
185186
if (options->fio_opts) {
186187
meta_request->fio_opts = *options->fio_opts;
187-
} else if (client != NULL) {
188+
} else if (client != NULL && client->fio_options_set) {
188189
meta_request->fio_opts = client->fio_opts;
190+
} else {
191+
/* Take a default options. */
192+
meta_request->fio_opts.should_stream = should_default_streaming;
193+
}
194+
195+
if (meta_request->fio_opts.should_stream && meta_request->fio_opts.disk_throughput_gbps == 0) {
196+
/* If disk throughput is not set, set it to the default. */
197+
meta_request->fio_opts.disk_throughput_gbps = g_default_throughput_target_gbps;
189198
}
190199

191200
/* Set up reference count. */
@@ -333,7 +342,6 @@ int aws_s3_meta_request_init_base(
333342
goto error;
334343
}
335344
if (meta_request->fio_opts.direct_io && !meta_request->fio_opts.should_stream) {
336-
/* TODO: aws_system_info_page_size */
337345
size_t page_size = aws_system_info_page_size();
338346
if (part_size % page_size != 0) {
339347
AWS_LOGF_ERROR(

0 commit comments

Comments
 (0)