opendal 0.1.6.pre.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.standard.yml +20 -0
- data/.tool-versions +1 -0
- data/.yardopts +1 -0
- data/Cargo.toml +65 -0
- data/DEPENDENCIES.md +9 -0
- data/DEPENDENCIES.rust.tsv +277 -0
- data/Gemfile +35 -0
- data/README.md +159 -0
- data/Rakefile +149 -0
- data/build.rs +22 -0
- data/core/CHANGELOG.md +4929 -0
- data/core/CONTRIBUTING.md +61 -0
- data/core/Cargo.lock +10259 -0
- data/core/Cargo.toml +437 -0
- data/core/DEPENDENCIES.md +3 -0
- data/core/DEPENDENCIES.rust.tsv +185 -0
- data/core/LICENSE +201 -0
- data/core/README.md +228 -0
- data/core/benches/README.md +18 -0
- data/core/benches/ops/README.md +26 -0
- data/core/benches/ops/main.rs +25 -0
- data/core/benches/ops/read.rs +100 -0
- data/core/benches/ops/utils.rs +59 -0
- data/core/benches/ops/write.rs +106 -0
- data/core/benches/types/README.md +9 -0
- data/core/benches/types/buffer.rs +114 -0
- data/core/benches/types/main.rs +23 -0
- data/core/benches/types/tasks.rs +64 -0
- data/core/benches/vs_fs/Cargo.toml +32 -0
- data/core/benches/vs_fs/README.md +35 -0
- data/core/benches/vs_fs/src/main.rs +83 -0
- data/core/benches/vs_s3/Cargo.toml +38 -0
- data/core/benches/vs_s3/README.md +55 -0
- data/core/benches/vs_s3/src/main.rs +123 -0
- data/core/edge/README.md +3 -0
- data/core/edge/file_write_on_full_disk/Cargo.toml +31 -0
- data/core/edge/file_write_on_full_disk/README.md +14 -0
- data/core/edge/file_write_on_full_disk/src/main.rs +43 -0
- data/core/edge/s3_aws_assume_role_with_web_identity/Cargo.toml +30 -0
- data/core/edge/s3_aws_assume_role_with_web_identity/README.md +18 -0
- data/core/edge/s3_aws_assume_role_with_web_identity/src/main.rs +34 -0
- data/core/edge/s3_read_on_wasm/.gitignore +3 -0
- data/core/edge/s3_read_on_wasm/Cargo.toml +38 -0
- data/core/edge/s3_read_on_wasm/README.md +42 -0
- data/core/edge/s3_read_on_wasm/src/lib.rs +60 -0
- data/core/edge/s3_read_on_wasm/webdriver.json +15 -0
- data/core/examples/README.md +23 -0
- data/core/examples/basic/Cargo.toml +29 -0
- data/core/examples/basic/README.md +15 -0
- data/core/examples/basic/src/main.rs +51 -0
- data/core/examples/concurrent-upload/Cargo.toml +29 -0
- data/core/examples/concurrent-upload/README.md +15 -0
- data/core/examples/concurrent-upload/src/main.rs +68 -0
- data/core/examples/multipart-upload/Cargo.toml +29 -0
- data/core/examples/multipart-upload/README.md +15 -0
- data/core/examples/multipart-upload/src/main.rs +56 -0
- data/core/fuzz/.gitignore +5 -0
- data/core/fuzz/Cargo.toml +92 -0
- data/core/fuzz/README.md +68 -0
- data/core/fuzz/fuzz_reader.rs +102 -0
- data/core/fuzz/fuzz_writer.rs +123 -0
- data/core/src/blocking/delete.rs +74 -0
- data/core/src/blocking/list.rs +71 -0
- data/core/src/blocking/mod.rs +33 -0
- data/core/src/blocking/operator.rs +729 -0
- data/core/src/blocking/read/buffer_iterator.rs +66 -0
- data/core/src/blocking/read/mod.rs +27 -0
- data/core/src/blocking/read/reader.rs +124 -0
- data/core/src/blocking/read/std_bytes_iterator.rs +69 -0
- data/core/src/blocking/read/std_reader.rs +95 -0
- data/core/src/blocking/write/mod.rs +22 -0
- data/core/src/blocking/write/std_writer.rs +82 -0
- data/core/src/blocking/write/writer.rs +109 -0
- data/core/src/docs/comparisons/mod.rs +30 -0
- data/core/src/docs/comparisons/vs_object_store.md +183 -0
- data/core/src/docs/concepts.rs +135 -0
- data/core/src/docs/internals/accessor.rs +306 -0
- data/core/src/docs/internals/layer.rs +42 -0
- data/core/src/docs/internals/mod.rs +62 -0
- data/core/src/docs/mod.rs +43 -0
- data/core/src/docs/performance/concurrent_write.md +101 -0
- data/core/src/docs/performance/http_optimization.md +124 -0
- data/core/src/docs/performance/mod.rs +32 -0
- data/core/src/docs/rfcs/0000_example.md +74 -0
- data/core/src/docs/rfcs/0000_foyer_integration.md +111 -0
- data/core/src/docs/rfcs/0041_object_native_api.md +185 -0
- data/core/src/docs/rfcs/0044_error_handle.md +198 -0
- data/core/src/docs/rfcs/0057_auto_region.md +160 -0
- data/core/src/docs/rfcs/0069_object_stream.md +145 -0
- data/core/src/docs/rfcs/0090_limited_reader.md +155 -0
- data/core/src/docs/rfcs/0112_path_normalization.md +79 -0
- data/core/src/docs/rfcs/0191_async_streaming_io.md +328 -0
- data/core/src/docs/rfcs/0203_remove_credential.md +96 -0
- data/core/src/docs/rfcs/0221_create_dir.md +89 -0
- data/core/src/docs/rfcs/0247_retryable_error.md +87 -0
- data/core/src/docs/rfcs/0293_object_id.md +67 -0
- data/core/src/docs/rfcs/0337_dir_entry.md +191 -0
- data/core/src/docs/rfcs/0409_accessor_capabilities.md +67 -0
- data/core/src/docs/rfcs/0413_presign.md +154 -0
- data/core/src/docs/rfcs/0423_command_line_interface.md +268 -0
- data/core/src/docs/rfcs/0429_init_from_iter.md +107 -0
- data/core/src/docs/rfcs/0438_multipart.md +163 -0
- data/core/src/docs/rfcs/0443_gateway.md +73 -0
- data/core/src/docs/rfcs/0501_new_builder.md +111 -0
- data/core/src/docs/rfcs/0554_write_refactor.md +96 -0
- data/core/src/docs/rfcs/0561_list_metadata_reuse.md +210 -0
- data/core/src/docs/rfcs/0599_blocking_api.md +157 -0
- data/core/src/docs/rfcs/0623_redis_service.md +300 -0
- data/core/src/docs/rfcs/0627_split_capabilities.md +89 -0
- data/core/src/docs/rfcs/0661_path_in_accessor.md +126 -0
- data/core/src/docs/rfcs/0793_generic_kv_services.md +209 -0
- data/core/src/docs/rfcs/0926_object_reader.md +93 -0
- data/core/src/docs/rfcs/0977_refactor_error.md +151 -0
- data/core/src/docs/rfcs/1085_object_handler.md +73 -0
- data/core/src/docs/rfcs/1391_object_metadataer.md +110 -0
- data/core/src/docs/rfcs/1398_query_based_metadata.md +125 -0
- data/core/src/docs/rfcs/1420_object_writer.md +147 -0
- data/core/src/docs/rfcs/1477_remove_object_concept.md +159 -0
- data/core/src/docs/rfcs/1735_operation_extension.md +117 -0
- data/core/src/docs/rfcs/2083_writer_sink_api.md +106 -0
- data/core/src/docs/rfcs/2133_append_api.md +88 -0
- data/core/src/docs/rfcs/2299_chain_based_operator_api.md +99 -0
- data/core/src/docs/rfcs/2602_object_versioning.md +138 -0
- data/core/src/docs/rfcs/2758_merge_append_into_write.md +79 -0
- data/core/src/docs/rfcs/2774_lister_api.md +66 -0
- data/core/src/docs/rfcs/2779_list_with_metakey.md +143 -0
- data/core/src/docs/rfcs/2852_native_capability.md +58 -0
- data/core/src/docs/rfcs/2884_merge_range_read_into_read.md +80 -0
- data/core/src/docs/rfcs/3017_remove_write_copy_from.md +94 -0
- data/core/src/docs/rfcs/3197_config.md +237 -0
- data/core/src/docs/rfcs/3232_align_list_api.md +69 -0
- data/core/src/docs/rfcs/3243_list_prefix.md +128 -0
- data/core/src/docs/rfcs/3356_lazy_reader.md +111 -0
- data/core/src/docs/rfcs/3526_list_recursive.md +59 -0
- data/core/src/docs/rfcs/3574_concurrent_stat_in_list.md +80 -0
- data/core/src/docs/rfcs/3734_buffered_reader.md +64 -0
- data/core/src/docs/rfcs/3898_concurrent_writer.md +66 -0
- data/core/src/docs/rfcs/3911_deleter_api.md +165 -0
- data/core/src/docs/rfcs/4382_range_based_read.md +213 -0
- data/core/src/docs/rfcs/4638_executor.md +215 -0
- data/core/src/docs/rfcs/5314_remove_metakey.md +120 -0
- data/core/src/docs/rfcs/5444_operator_from_uri.md +162 -0
- data/core/src/docs/rfcs/5479_context.md +140 -0
- data/core/src/docs/rfcs/5485_conditional_reader.md +112 -0
- data/core/src/docs/rfcs/5495_list_with_deleted.md +81 -0
- data/core/src/docs/rfcs/5556_write_returns_metadata.md +121 -0
- data/core/src/docs/rfcs/5871_read_returns_metadata.md +112 -0
- data/core/src/docs/rfcs/6189_remove_native_blocking.md +106 -0
- data/core/src/docs/rfcs/6209_glob_support.md +132 -0
- data/core/src/docs/rfcs/6213_options_api.md +142 -0
- data/core/src/docs/rfcs/README.md +62 -0
- data/core/src/docs/rfcs/mod.rs +278 -0
- data/core/src/docs/upgrade.md +1556 -0
- data/core/src/layers/async_backtrace.rs +174 -0
- data/core/src/layers/await_tree.rs +202 -0
- data/core/src/layers/capability_check.rs +239 -0
- data/core/src/layers/chaos.rs +170 -0
- data/core/src/layers/complete.rs +385 -0
- data/core/src/layers/concurrent_limit.rs +322 -0
- data/core/src/layers/correctness_check.rs +440 -0
- data/core/src/layers/dtrace.rs +294 -0
- data/core/src/layers/error_context.rs +310 -0
- data/core/src/layers/fastmetrics.rs +525 -0
- data/core/src/layers/fastrace.rs +271 -0
- data/core/src/layers/http_client.rs +206 -0
- data/core/src/layers/immutable_index.rs +408 -0
- data/core/src/layers/logging.rs +842 -0
- data/core/src/layers/metrics.rs +182 -0
- data/core/src/layers/mime_guess.rs +199 -0
- data/core/src/layers/mod.rs +130 -0
- data/core/src/layers/observe/metrics.rs +936 -0
- data/core/src/layers/observe/mod.rs +93 -0
- data/core/src/layers/otelmetrics.rs +496 -0
- data/core/src/layers/oteltrace.rs +203 -0
- data/core/src/layers/prometheus.rs +686 -0
- data/core/src/layers/prometheus_client.rs +519 -0
- data/core/src/layers/retry.rs +933 -0
- data/core/src/layers/throttle.rs +204 -0
- data/core/src/layers/timeout.rs +513 -0
- data/core/src/layers/tracing.rs +349 -0
- data/core/src/layers/type_eraser.rs +91 -0
- data/core/src/lib.rs +204 -0
- data/core/src/raw/accessor.rs +856 -0
- data/core/src/raw/adapters/kv/api.rs +164 -0
- data/core/src/raw/adapters/kv/backend.rs +253 -0
- data/core/src/raw/adapters/kv/mod.rs +31 -0
- data/core/src/raw/adapters/mod.rs +50 -0
- data/core/src/raw/adapters/typed_kv/api.rs +171 -0
- data/core/src/raw/adapters/typed_kv/backend.rs +279 -0
- data/core/src/raw/adapters/typed_kv/mod.rs +29 -0
- data/core/src/raw/atomic_util.rs +57 -0
- data/core/src/raw/azure.rs +570 -0
- data/core/src/raw/chrono_util.rs +109 -0
- data/core/src/raw/enum_utils.rs +201 -0
- data/core/src/raw/futures_util.rs +470 -0
- data/core/src/raw/http_util/body.rs +144 -0
- data/core/src/raw/http_util/bytes_content_range.rs +239 -0
- data/core/src/raw/http_util/bytes_range.rs +260 -0
- data/core/src/raw/http_util/client.rs +276 -0
- data/core/src/raw/http_util/error.rs +68 -0
- data/core/src/raw/http_util/header.rs +356 -0
- data/core/src/raw/http_util/mod.rs +78 -0
- data/core/src/raw/http_util/multipart.rs +1180 -0
- data/core/src/raw/http_util/uri.rs +190 -0
- data/core/src/raw/layer.rs +295 -0
- data/core/src/raw/mod.rs +101 -0
- data/core/src/raw/oio/buf/flex_buf.rs +118 -0
- data/core/src/raw/oio/buf/mod.rs +25 -0
- data/core/src/raw/oio/buf/pooled_buf.rs +126 -0
- data/core/src/raw/oio/buf/queue_buf.rs +117 -0
- data/core/src/raw/oio/delete/api.rs +102 -0
- data/core/src/raw/oio/delete/batch_delete.rs +127 -0
- data/core/src/raw/oio/delete/mod.rs +30 -0
- data/core/src/raw/oio/delete/one_shot_delete.rs +79 -0
- data/core/src/raw/oio/entry.rs +89 -0
- data/core/src/raw/oio/list/api.rs +69 -0
- data/core/src/raw/oio/list/flat_list.rs +137 -0
- data/core/src/raw/oio/list/hierarchy_list.rs +135 -0
- data/core/src/raw/oio/list/mod.rs +35 -0
- data/core/src/raw/oio/list/page_list.rs +105 -0
- data/core/src/raw/oio/list/prefix_list.rs +64 -0
- data/core/src/raw/oio/mod.rs +40 -0
- data/core/src/raw/oio/read/api.rs +119 -0
- data/core/src/raw/oio/read/mod.rs +21 -0
- data/core/src/raw/oio/write/api.rs +103 -0
- data/core/src/raw/oio/write/append_write.rs +111 -0
- data/core/src/raw/oio/write/block_write.rs +405 -0
- data/core/src/raw/oio/write/mod.rs +42 -0
- data/core/src/raw/oio/write/multipart_write.rs +518 -0
- data/core/src/raw/oio/write/one_shot_write.rs +77 -0
- data/core/src/raw/oio/write/position_write.rs +284 -0
- data/core/src/raw/operation.rs +88 -0
- data/core/src/raw/ops.rs +917 -0
- data/core/src/raw/path.rs +451 -0
- data/core/src/raw/path_cache.rs +244 -0
- data/core/src/raw/rps.rs +249 -0
- data/core/src/raw/serde_util.rs +423 -0
- data/core/src/raw/std_io_util.rs +65 -0
- data/core/src/raw/tests/mod.rs +30 -0
- data/core/src/raw/tests/read.rs +116 -0
- data/core/src/raw/tests/utils.rs +80 -0
- data/core/src/raw/tests/write.rs +79 -0
- data/core/src/raw/tokio_util.rs +24 -0
- data/core/src/raw/version.rs +19 -0
- data/core/src/services/aliyun_drive/backend.rs +421 -0
- data/core/src/services/aliyun_drive/config.rs +72 -0
- data/core/src/services/aliyun_drive/core.rs +651 -0
- data/core/src/services/aliyun_drive/delete.rs +51 -0
- data/core/src/services/aliyun_drive/docs.md +61 -0
- data/core/src/services/aliyun_drive/error.rs +56 -0
- data/core/src/services/aliyun_drive/lister.rs +134 -0
- data/core/src/services/aliyun_drive/mod.rs +39 -0
- data/core/src/services/aliyun_drive/writer.rs +114 -0
- data/core/src/services/alluxio/backend.rs +257 -0
- data/core/src/services/alluxio/config.rs +50 -0
- data/core/src/services/alluxio/core.rs +367 -0
- data/core/src/services/alluxio/delete.rs +38 -0
- data/core/src/services/alluxio/docs.md +45 -0
- data/core/src/services/alluxio/error.rs +99 -0
- data/core/src/services/alluxio/lister.rs +73 -0
- data/core/src/services/alluxio/mod.rs +39 -0
- data/core/src/services/alluxio/writer.rs +74 -0
- data/core/src/services/azblob/backend.rs +594 -0
- data/core/src/services/azblob/config.rs +220 -0
- data/core/src/services/azblob/core.rs +937 -0
- data/core/src/services/azblob/delete.rs +108 -0
- data/core/src/services/azblob/docs.md +77 -0
- data/core/src/services/azblob/error.rs +164 -0
- data/core/src/services/azblob/lister.rs +107 -0
- data/core/src/services/azblob/mod.rs +38 -0
- data/core/src/services/azblob/writer.rs +177 -0
- data/core/src/services/azdls/backend.rs +435 -0
- data/core/src/services/azdls/config.rs +89 -0
- data/core/src/services/azdls/core.rs +388 -0
- data/core/src/services/azdls/delete.rs +48 -0
- data/core/src/services/azdls/docs.md +73 -0
- data/core/src/services/azdls/error.rs +107 -0
- data/core/src/services/azdls/lister.rs +165 -0
- data/core/src/services/azdls/mod.rs +38 -0
- data/core/src/services/azdls/writer.rs +129 -0
- data/core/src/services/azfile/backend.rs +373 -0
- data/core/src/services/azfile/config.rs +61 -0
- data/core/src/services/azfile/core.rs +435 -0
- data/core/src/services/azfile/delete.rs +51 -0
- data/core/src/services/azfile/docs.md +65 -0
- data/core/src/services/azfile/error.rs +108 -0
- data/core/src/services/azfile/lister.rs +217 -0
- data/core/src/services/azfile/mod.rs +39 -0
- data/core/src/services/azfile/writer.rs +92 -0
- data/core/src/services/b2/backend.rs +434 -0
- data/core/src/services/b2/config.rs +64 -0
- data/core/src/services/b2/core.rs +742 -0
- data/core/src/services/b2/delete.rs +56 -0
- data/core/src/services/b2/docs.md +54 -0
- data/core/src/services/b2/error.rs +132 -0
- data/core/src/services/b2/lister.rs +110 -0
- data/core/src/services/b2/mod.rs +39 -0
- data/core/src/services/b2/writer.rs +189 -0
- data/core/src/services/cacache/backend.rs +160 -0
- data/core/src/services/cacache/config.rs +28 -0
- data/core/src/services/cacache/core.rs +96 -0
- data/core/src/services/cacache/delete.rs +39 -0
- data/core/src/services/cacache/docs.md +38 -0
- data/core/src/services/cacache/mod.rs +34 -0
- data/core/src/services/cacache/writer.rs +61 -0
- data/core/src/services/cloudflare_kv/backend.rs +513 -0
- data/core/src/services/cloudflare_kv/config.rs +55 -0
- data/core/src/services/cloudflare_kv/core.rs +168 -0
- data/core/src/services/cloudflare_kv/delete.rs +119 -0
- data/core/src/services/cloudflare_kv/docs.md +21 -0
- data/core/src/services/cloudflare_kv/error.rs +79 -0
- data/core/src/services/cloudflare_kv/lister.rs +170 -0
- data/core/src/services/cloudflare_kv/mod.rs +39 -0
- data/core/src/services/cloudflare_kv/model.rs +76 -0
- data/core/src/services/cloudflare_kv/writer.rs +68 -0
- data/core/src/services/compfs/backend.rs +290 -0
- data/core/src/services/compfs/config.rs +30 -0
- data/core/src/services/compfs/core.rs +159 -0
- data/core/src/services/compfs/delete.rs +53 -0
- data/core/src/services/compfs/lister.rs +98 -0
- data/core/src/services/compfs/mod.rs +38 -0
- data/core/src/services/compfs/reader.rs +79 -0
- data/core/src/services/compfs/writer.rs +90 -0
- data/core/src/services/cos/backend.rs +442 -0
- data/core/src/services/cos/config.rs +54 -0
- data/core/src/services/cos/core.rs +761 -0
- data/core/src/services/cos/delete.rs +48 -0
- data/core/src/services/cos/docs.md +55 -0
- data/core/src/services/cos/error.rs +105 -0
- data/core/src/services/cos/lister.rs +237 -0
- data/core/src/services/cos/mod.rs +39 -0
- data/core/src/services/cos/writer.rs +234 -0
- data/core/src/services/d1/backend.rs +330 -0
- data/core/src/services/d1/config.rs +55 -0
- data/core/src/services/d1/docs.md +48 -0
- data/core/src/services/d1/error.rs +79 -0
- data/core/src/services/d1/mod.rs +29 -0
- data/core/src/services/d1/model.rs +125 -0
- data/core/src/services/dashmap/backend.rs +203 -0
- data/core/src/services/dashmap/config.rs +37 -0
- data/core/src/services/dashmap/core.rs +61 -0
- data/core/src/services/dashmap/delete.rs +40 -0
- data/core/src/services/dashmap/docs.md +38 -0
- data/core/src/services/dashmap/lister.rs +63 -0
- data/core/src/services/dashmap/mod.rs +36 -0
- data/core/src/services/dashmap/writer.rs +87 -0
- data/core/src/services/dbfs/backend.rs +258 -0
- data/core/src/services/dbfs/config.rs +48 -0
- data/core/src/services/dbfs/core.rs +191 -0
- data/core/src/services/dbfs/delete.rs +49 -0
- data/core/src/services/dbfs/docs.md +57 -0
- data/core/src/services/dbfs/error.rs +74 -0
- data/core/src/services/dbfs/lister.rs +96 -0
- data/core/src/services/dbfs/mod.rs +38 -0
- data/core/src/services/dbfs/writer.rs +64 -0
- data/core/src/services/dropbox/backend.rs +187 -0
- data/core/src/services/dropbox/builder.rs +222 -0
- data/core/src/services/dropbox/config.rs +47 -0
- data/core/src/services/dropbox/core.rs +496 -0
- data/core/src/services/dropbox/delete.rs +54 -0
- data/core/src/services/dropbox/docs.md +64 -0
- data/core/src/services/dropbox/error.rs +85 -0
- data/core/src/services/dropbox/lister.rs +117 -0
- data/core/src/services/dropbox/mod.rs +40 -0
- data/core/src/services/dropbox/writer.rs +51 -0
- data/core/src/services/etcd/backend.rs +345 -0
- data/core/src/services/etcd/config.rs +86 -0
- data/core/src/services/etcd/core.rs +143 -0
- data/core/src/services/etcd/deleter.rs +41 -0
- data/core/src/services/etcd/docs.md +45 -0
- data/core/src/services/etcd/error.rs +26 -0
- data/core/src/services/etcd/lister.rs +79 -0
- data/core/src/services/etcd/mod.rs +36 -0
- data/core/src/services/etcd/writer.rs +61 -0
- data/core/src/services/foundationdb/backend.rs +171 -0
- data/core/src/services/foundationdb/config.rs +45 -0
- data/core/src/services/foundationdb/docs.md +42 -0
- data/core/src/services/foundationdb/mod.rs +24 -0
- data/core/src/services/fs/backend.rs +299 -0
- data/core/src/services/fs/config.rs +33 -0
- data/core/src/services/fs/core.rs +227 -0
- data/core/src/services/fs/delete.rs +53 -0
- data/core/src/services/fs/docs.md +49 -0
- data/core/src/services/fs/error.rs +31 -0
- data/core/src/services/fs/lister.rs +81 -0
- data/core/src/services/fs/mod.rs +40 -0
- data/core/src/services/fs/reader.rs +83 -0
- data/core/src/services/fs/writer.rs +212 -0
- data/core/src/services/ftp/backend.rs +388 -0
- data/core/src/services/ftp/config.rs +46 -0
- data/core/src/services/ftp/core.rs +136 -0
- data/core/src/services/ftp/delete.rs +62 -0
- data/core/src/services/ftp/docs.md +42 -0
- data/core/src/services/ftp/err.rs +47 -0
- data/core/src/services/ftp/lister.rs +72 -0
- data/core/src/services/ftp/mod.rs +41 -0
- data/core/src/services/ftp/reader.rs +84 -0
- data/core/src/services/ftp/writer.rs +122 -0
- data/core/src/services/gcs/backend.rs +499 -0
- data/core/src/services/gcs/config.rs +168 -0
- data/core/src/services/gcs/core.rs +1079 -0
- data/core/src/services/gcs/delete.rs +98 -0
- data/core/src/services/gcs/docs.md +76 -0
- data/core/src/services/gcs/error.rs +122 -0
- data/core/src/services/gcs/lister.rs +136 -0
- data/core/src/services/gcs/mod.rs +40 -0
- data/core/src/services/gcs/uri.rs +75 -0
- data/core/src/services/gcs/writer.rs +163 -0
- data/core/src/services/gdrive/backend.rs +176 -0
- data/core/src/services/gdrive/builder.rs +228 -0
- data/core/src/services/gdrive/config.rs +47 -0
- data/core/src/services/gdrive/core.rs +499 -0
- data/core/src/services/gdrive/delete.rs +57 -0
- data/core/src/services/gdrive/docs.md +65 -0
- data/core/src/services/gdrive/error.rs +80 -0
- data/core/src/services/gdrive/lister.rs +110 -0
- data/core/src/services/gdrive/mod.rs +40 -0
- data/core/src/services/gdrive/writer.rs +77 -0
- data/core/src/services/ghac/backend.rs +285 -0
- data/core/src/services/ghac/config.rs +36 -0
- data/core/src/services/ghac/core.rs +459 -0
- data/core/src/services/ghac/docs.md +84 -0
- data/core/src/services/ghac/error.rs +52 -0
- data/core/src/services/ghac/mod.rs +35 -0
- data/core/src/services/ghac/writer.rs +201 -0
- data/core/src/services/github/backend.rs +285 -0
- data/core/src/services/github/config.rs +59 -0
- data/core/src/services/github/core.rs +351 -0
- data/core/src/services/github/delete.rs +41 -0
- data/core/src/services/github/docs.md +52 -0
- data/core/src/services/github/error.rs +101 -0
- data/core/src/services/github/lister.rs +112 -0
- data/core/src/services/github/mod.rs +38 -0
- data/core/src/services/github/writer.rs +51 -0
- data/core/src/services/gridfs/backend.rs +166 -0
- data/core/src/services/gridfs/config.rs +50 -0
- data/core/src/services/gridfs/core.rs +154 -0
- data/core/src/services/gridfs/docs.md +46 -0
- data/core/src/services/gridfs/mod.rs +26 -0
- data/core/src/services/hdfs/backend.rs +413 -0
- data/core/src/services/hdfs/config.rs +59 -0
- data/core/src/services/hdfs/delete.rs +62 -0
- data/core/src/services/hdfs/docs.md +140 -0
- data/core/src/services/hdfs/lister.rs +70 -0
- data/core/src/services/hdfs/mod.rs +36 -0
- data/core/src/services/hdfs/reader.rs +79 -0
- data/core/src/services/hdfs/writer.rs +104 -0
- data/core/src/services/hdfs_native/backend.rs +340 -0
- data/core/src/services/hdfs_native/config.rs +45 -0
- data/core/src/services/hdfs_native/delete.rs +47 -0
- data/core/src/services/hdfs_native/docs.md +35 -0
- data/core/src/services/hdfs_native/error.rs +59 -0
- data/core/src/services/hdfs_native/lister.rs +85 -0
- data/core/src/services/hdfs_native/mod.rs +39 -0
- data/core/src/services/hdfs_native/reader.rs +62 -0
- data/core/src/services/hdfs_native/writer.rs +61 -0
- data/core/src/services/http/backend.rs +291 -0
- data/core/src/services/http/config.rs +49 -0
- data/core/src/services/http/core.rs +125 -0
- data/core/src/services/http/docs.md +45 -0
- data/core/src/services/http/error.rs +53 -0
- data/core/src/services/http/mod.rs +32 -0
- data/core/src/services/huggingface/backend.rs +289 -0
- data/core/src/services/huggingface/config.rs +75 -0
- data/core/src/services/huggingface/core.rs +406 -0
- data/core/src/services/huggingface/docs.md +61 -0
- data/core/src/services/huggingface/error.rs +93 -0
- data/core/src/services/huggingface/lister.rs +91 -0
- data/core/src/services/huggingface/mod.rs +34 -0
- data/core/src/services/ipfs/backend.rs +257 -0
- data/core/src/services/ipfs/config.rs +32 -0
- data/core/src/services/ipfs/core.rs +239 -0
- data/core/src/services/ipfs/docs.md +45 -0
- data/core/src/services/ipfs/error.rs +52 -0
- data/core/src/services/ipfs/ipld.rs +162 -0
- data/core/src/services/ipfs/mod.rs +34 -0
- data/core/src/services/ipmfs/backend.rs +147 -0
- data/core/src/services/ipmfs/builder.rs +166 -0
- data/core/src/services/ipmfs/config.rs +32 -0
- data/core/src/services/ipmfs/core.rs +142 -0
- data/core/src/services/ipmfs/delete.rs +48 -0
- data/core/src/services/ipmfs/docs.md +14 -0
- data/core/src/services/ipmfs/error.rs +83 -0
- data/core/src/services/ipmfs/lister.rs +135 -0
- data/core/src/services/ipmfs/mod.rs +40 -0
- data/core/src/services/ipmfs/writer.rs +49 -0
- data/core/src/services/koofr/backend.rs +361 -0
- data/core/src/services/koofr/config.rs +50 -0
- data/core/src/services/koofr/core.rs +458 -0
- data/core/src/services/koofr/delete.rs +50 -0
- data/core/src/services/koofr/docs.md +51 -0
- data/core/src/services/koofr/error.rs +72 -0
- data/core/src/services/koofr/lister.rs +88 -0
- data/core/src/services/koofr/mod.rs +38 -0
- data/core/src/services/koofr/writer.rs +53 -0
- data/core/src/services/lakefs/backend.rs +309 -0
- data/core/src/services/lakefs/config.rs +81 -0
- data/core/src/services/lakefs/core.rs +261 -0
- data/core/src/services/lakefs/delete.rs +54 -0
- data/core/src/services/lakefs/docs.md +62 -0
- data/core/src/services/lakefs/error.rs +93 -0
- data/core/src/services/lakefs/lister.rs +120 -0
- data/core/src/services/lakefs/mod.rs +38 -0
- data/core/src/services/lakefs/writer.rs +50 -0
- data/core/src/services/memcached/backend.rs +284 -0
- data/core/src/services/memcached/binary.rs +289 -0
- data/core/src/services/memcached/config.rs +43 -0
- data/core/src/services/memcached/docs.md +47 -0
- data/core/src/services/memcached/mod.rs +27 -0
- data/core/src/services/memory/backend.rs +205 -0
- data/core/src/services/memory/config.rs +30 -0
- data/core/src/services/memory/core.rs +80 -0
- data/core/src/services/memory/delete.rs +42 -0
- data/core/src/services/memory/docs.md +36 -0
- data/core/src/services/memory/lister.rs +56 -0
- data/core/src/services/memory/mod.rs +36 -0
- data/core/src/services/memory/writer.rs +85 -0
- data/core/src/services/mini_moka/backend.rs +260 -0
- data/core/src/services/mini_moka/config.rs +56 -0
- data/core/src/services/mini_moka/core.rs +52 -0
- data/core/src/services/mini_moka/delete.rs +42 -0
- data/core/src/services/mini_moka/docs.md +19 -0
- data/core/src/services/mini_moka/lister.rs +68 -0
- data/core/src/services/mini_moka/mod.rs +36 -0
- data/core/src/services/mini_moka/writer.rs +84 -0
- data/core/src/services/mod.rs +206 -0
- data/core/src/services/moka/backend.rs +326 -0
- data/core/src/services/moka/config.rs +59 -0
- data/core/src/services/moka/core.rs +62 -0
- data/core/src/services/moka/delete.rs +42 -0
- data/core/src/services/moka/docs.md +42 -0
- data/core/src/services/moka/lister.rs +65 -0
- data/core/src/services/moka/mod.rs +41 -0
- data/core/src/services/moka/writer.rs +83 -0
- data/core/src/services/mongodb/backend.rs +291 -0
- data/core/src/services/mongodb/config.rs +54 -0
- data/core/src/services/mongodb/docs.md +49 -0
- data/core/src/services/mongodb/mod.rs +24 -0
- data/core/src/services/monoiofs/backend.rs +238 -0
- data/core/src/services/monoiofs/config.rs +34 -0
- data/core/src/services/monoiofs/core.rs +313 -0
- data/core/src/services/monoiofs/delete.rs +64 -0
- data/core/src/services/monoiofs/docs.md +46 -0
- data/core/src/services/monoiofs/mod.rs +36 -0
- data/core/src/services/monoiofs/reader.rs +147 -0
- data/core/src/services/monoiofs/writer.rs +189 -0
- data/core/src/services/mysql/backend.rs +256 -0
- data/core/src/services/mysql/config.rs +66 -0
- data/core/src/services/mysql/docs.md +47 -0
- data/core/src/services/mysql/mod.rs +24 -0
- data/core/src/services/obs/backend.rs +442 -0
- data/core/src/services/obs/config.rs +53 -0
- data/core/src/services/obs/core.rs +608 -0
- data/core/src/services/obs/delete.rs +48 -0
- data/core/src/services/obs/docs.md +54 -0
- data/core/src/services/obs/error.rs +106 -0
- data/core/src/services/obs/lister.rs +101 -0
- data/core/src/services/obs/mod.rs +38 -0
- data/core/src/services/obs/writer.rs +235 -0
- data/core/src/services/onedrive/backend.rs +127 -0
- data/core/src/services/onedrive/builder.rs +236 -0
- data/core/src/services/onedrive/config.rs +49 -0
- data/core/src/services/onedrive/core.rs +691 -0
- data/core/src/services/onedrive/delete.rs +47 -0
- data/core/src/services/onedrive/docs.md +115 -0
- data/core/src/services/onedrive/error.rs +61 -0
- data/core/src/services/onedrive/graph_model.rs +425 -0
- data/core/src/services/onedrive/lister.rs +150 -0
- data/core/src/services/onedrive/mod.rs +42 -0
- data/core/src/services/onedrive/writer.rs +168 -0
- data/core/src/services/opfs/backend.rs +50 -0
- data/core/src/services/opfs/config.rs +25 -0
- data/core/src/services/opfs/core.rs +74 -0
- data/core/src/services/opfs/docs.md +18 -0
- data/core/src/services/opfs/error.rs +27 -0
- data/core/src/services/opfs/mod.rs +30 -0
- data/core/src/services/opfs/utils.rs +70 -0
- data/core/src/services/oss/backend.rs +734 -0
- data/core/src/services/oss/config.rs +113 -0
- data/core/src/services/oss/core.rs +1088 -0
- data/core/src/services/oss/delete.rs +109 -0
- data/core/src/services/oss/docs.md +74 -0
- data/core/src/services/oss/error.rs +109 -0
- data/core/src/services/oss/lister.rs +256 -0
- data/core/src/services/oss/mod.rs +38 -0
- data/core/src/services/oss/writer.rs +228 -0
- data/core/src/services/pcloud/backend.rs +358 -0
- data/core/src/services/pcloud/config.rs +51 -0
- data/core/src/services/pcloud/core.rs +461 -0
- data/core/src/services/pcloud/delete.rs +66 -0
- data/core/src/services/pcloud/docs.md +51 -0
- data/core/src/services/pcloud/error.rs +88 -0
- data/core/src/services/pcloud/lister.rs +95 -0
- data/core/src/services/pcloud/mod.rs +38 -0
- data/core/src/services/pcloud/writer.rs +66 -0
- data/core/src/services/persy/backend.rs +226 -0
- data/core/src/services/persy/config.rs +32 -0
- data/core/src/services/persy/docs.md +43 -0
- data/core/src/services/persy/mod.rs +24 -0
- data/core/src/services/postgresql/backend.rs +258 -0
- data/core/src/services/postgresql/config.rs +66 -0
- data/core/src/services/postgresql/docs.md +47 -0
- data/core/src/services/postgresql/mod.rs +24 -0
- data/core/src/services/redb/backend.rs +280 -0
- data/core/src/services/redb/config.rs +34 -0
- data/core/src/services/redb/docs.md +41 -0
- data/core/src/services/redb/mod.rs +24 -0
- data/core/src/services/redis/backend.rs +442 -0
- data/core/src/services/redis/config.rs +79 -0
- data/core/src/services/redis/core.rs +209 -0
- data/core/src/services/redis/delete.rs +40 -0
- data/core/src/services/redis/docs.md +43 -0
- data/core/src/services/redis/mod.rs +34 -0
- data/core/src/services/redis/writer.rs +57 -0
- data/core/src/services/rocksdb/backend.rs +159 -0
- data/core/src/services/rocksdb/config.rs +34 -0
- data/core/src/services/rocksdb/docs.md +54 -0
- data/core/src/services/rocksdb/mod.rs +24 -0
- data/core/src/services/s3/backend.rs +1293 -0
- data/core/src/services/s3/compatible_services.md +126 -0
- data/core/src/services/s3/config.rs +327 -0
- data/core/src/services/s3/core.rs +1741 -0
- data/core/src/services/s3/delete.rs +109 -0
- data/core/src/services/s3/docs.md +244 -0
- data/core/src/services/s3/error.rs +171 -0
- data/core/src/services/s3/lister.rs +405 -0
- data/core/src/services/s3/mod.rs +38 -0
- data/core/src/services/s3/writer.rs +262 -0
- data/core/src/services/seafile/backend.rs +297 -0
- data/core/src/services/seafile/config.rs +56 -0
- data/core/src/services/seafile/core.rs +475 -0
- data/core/src/services/seafile/delete.rs +40 -0
- data/core/src/services/seafile/docs.md +54 -0
- data/core/src/services/seafile/error.rs +86 -0
- data/core/src/services/seafile/lister.rs +83 -0
- data/core/src/services/seafile/mod.rs +38 -0
- data/core/src/services/seafile/writer.rs +55 -0
- data/core/src/services/sftp/backend.rs +397 -0
- data/core/src/services/sftp/config.rs +50 -0
- data/core/src/services/sftp/core.rs +154 -0
- data/core/src/services/sftp/delete.rs +55 -0
- data/core/src/services/sftp/docs.md +49 -0
- data/core/src/services/sftp/error.rs +57 -0
- data/core/src/services/sftp/lister.rs +88 -0
- data/core/src/services/sftp/mod.rs +42 -0
- data/core/src/services/sftp/reader.rs +78 -0
- data/core/src/services/sftp/utils.rs +51 -0
- data/core/src/services/sftp/writer.rs +67 -0
- data/core/src/services/sled/backend.rs +194 -0
- data/core/src/services/sled/config.rs +45 -0
- data/core/src/services/sled/docs.md +39 -0
- data/core/src/services/sled/mod.rs +24 -0
- data/core/src/services/sqlite/backend.rs +326 -0
- data/core/src/services/sqlite/config.rs +70 -0
- data/core/src/services/sqlite/docs.md +46 -0
- data/core/src/services/sqlite/mod.rs +24 -0
- data/core/src/services/surrealdb/backend.rs +365 -0
- data/core/src/services/surrealdb/config.rs +64 -0
- data/core/src/services/surrealdb/docs.md +54 -0
- data/core/src/services/surrealdb/mod.rs +24 -0
- data/core/src/services/swift/backend.rs +275 -0
- data/core/src/services/swift/compatible_services.md +53 -0
- data/core/src/services/swift/config.rs +53 -0
- data/core/src/services/swift/core.rs +310 -0
- data/core/src/services/swift/delete.rs +49 -0
- data/core/src/services/swift/docs.md +52 -0
- data/core/src/services/swift/error.rs +90 -0
- data/core/src/services/swift/lister.rs +119 -0
- data/core/src/services/swift/mod.rs +38 -0
- data/core/src/services/swift/writer.rs +53 -0
- data/core/src/services/tikv/backend.rs +237 -0
- data/core/src/services/tikv/config.rs +52 -0
- data/core/src/services/tikv/docs.md +43 -0
- data/core/src/services/tikv/mod.rs +24 -0
- data/core/src/services/upyun/backend.rs +317 -0
- data/core/src/services/upyun/config.rs +51 -0
- data/core/src/services/upyun/core.rs +521 -0
- data/core/src/services/upyun/delete.rs +50 -0
- data/core/src/services/upyun/docs.md +51 -0
- data/core/src/services/upyun/error.rs +97 -0
- data/core/src/services/upyun/lister.rs +101 -0
- data/core/src/services/upyun/mod.rs +38 -0
- data/core/src/services/upyun/writer.rs +127 -0
- data/core/src/services/vercel_artifacts/backend.rs +99 -0
- data/core/src/services/vercel_artifacts/builder.rs +117 -0
- data/core/src/services/vercel_artifacts/config.rs +39 -0
- data/core/src/services/vercel_artifacts/core.rs +112 -0
- data/core/src/services/vercel_artifacts/docs.md +40 -0
- data/core/src/services/vercel_artifacts/error.rs +50 -0
- data/core/src/services/vercel_artifacts/mod.rs +36 -0
- data/core/src/services/vercel_artifacts/writer.rs +58 -0
- data/core/src/services/vercel_blob/backend.rs +251 -0
- data/core/src/services/vercel_blob/config.rs +45 -0
- data/core/src/services/vercel_blob/core.rs +449 -0
- data/core/src/services/vercel_blob/delete.rs +38 -0
- data/core/src/services/vercel_blob/docs.md +45 -0
- data/core/src/services/vercel_blob/error.rs +110 -0
- data/core/src/services/vercel_blob/lister.rs +69 -0
- data/core/src/services/vercel_blob/mod.rs +38 -0
- data/core/src/services/vercel_blob/writer.rs +143 -0
- data/core/src/services/webdav/backend.rs +318 -0
- data/core/src/services/webdav/config.rs +53 -0
- data/core/src/services/webdav/core.rs +859 -0
- data/core/src/services/webdav/delete.rs +47 -0
- data/core/src/services/webdav/docs.md +49 -0
- data/core/src/services/webdav/error.rs +53 -0
- data/core/src/services/webdav/lister.rs +106 -0
- data/core/src/services/webdav/mod.rs +38 -0
- data/core/src/services/webdav/writer.rs +56 -0
- data/core/src/services/webhdfs/backend.rs +376 -0
- data/core/src/services/webhdfs/config.rs +52 -0
- data/core/src/services/webhdfs/core.rs +398 -0
- data/core/src/services/webhdfs/delete.rs +46 -0
- data/core/src/services/webhdfs/docs.md +90 -0
- data/core/src/services/webhdfs/error.rs +126 -0
- data/core/src/services/webhdfs/lister.rs +130 -0
- data/core/src/services/webhdfs/message.rs +249 -0
- data/core/src/services/webhdfs/mod.rs +41 -0
- data/core/src/services/webhdfs/writer.rs +177 -0
- data/core/src/services/yandex_disk/backend.rs +267 -0
- data/core/src/services/yandex_disk/config.rs +45 -0
- data/core/src/services/yandex_disk/core.rs +340 -0
- data/core/src/services/yandex_disk/delete.rs +54 -0
- data/core/src/services/yandex_disk/docs.md +45 -0
- data/core/src/services/yandex_disk/error.rs +104 -0
- data/core/src/services/yandex_disk/lister.rs +113 -0
- data/core/src/services/yandex_disk/mod.rs +38 -0
- data/core/src/services/yandex_disk/writer.rs +52 -0
- data/core/src/types/buffer.rs +991 -0
- data/core/src/types/builder.rs +152 -0
- data/core/src/types/capability.rs +209 -0
- data/core/src/types/context/mod.rs +22 -0
- data/core/src/types/context/read.rs +231 -0
- data/core/src/types/context/write.rs +441 -0
- data/core/src/types/delete/deleter.rs +220 -0
- data/core/src/types/delete/futures_delete_sink.rs +176 -0
- data/core/src/types/delete/input.rs +97 -0
- data/core/src/types/delete/mod.rs +26 -0
- data/core/src/types/entry.rs +69 -0
- data/core/src/types/error.rs +570 -0
- data/core/src/types/execute/api.rs +110 -0
- data/core/src/types/execute/executor.rs +96 -0
- data/core/src/types/execute/executors/mod.rs +27 -0
- data/core/src/types/execute/executors/tokio_executor.rs +60 -0
- data/core/src/types/execute/mod.rs +25 -0
- data/core/src/types/list.rs +137 -0
- data/core/src/types/metadata.rs +436 -0
- data/core/src/types/mod.rs +72 -0
- data/core/src/types/mode.rs +68 -0
- data/core/src/types/operator/builder.rs +535 -0
- data/core/src/types/operator/info.rs +63 -0
- data/core/src/types/operator/mod.rs +33 -0
- data/core/src/types/operator/operator.rs +2236 -0
- data/core/src/types/operator/operator_futures.rs +1430 -0
- data/core/src/types/operator/registry.rs +129 -0
- data/core/src/types/options.rs +548 -0
- data/core/src/types/read/buffer_stream.rs +273 -0
- data/core/src/types/read/futures_async_reader.rs +289 -0
- data/core/src/types/read/futures_bytes_stream.rs +157 -0
- data/core/src/types/read/mod.rs +29 -0
- data/core/src/types/read/reader.rs +604 -0
- data/core/src/types/scheme.rs +475 -0
- data/core/src/types/write/buffer_sink.rs +188 -0
- data/core/src/types/write/futures_async_writer.rs +136 -0
- data/core/src/types/write/futures_bytes_sink.rs +103 -0
- data/core/src/types/write/mod.rs +26 -0
- data/core/src/types/write/writer.rs +411 -0
- data/core/tests/behavior/README.md +77 -0
- data/core/tests/behavior/async_copy.rs +314 -0
- data/core/tests/behavior/async_create_dir.rs +53 -0
- data/core/tests/behavior/async_delete.rs +354 -0
- data/core/tests/behavior/async_list.rs +739 -0
- data/core/tests/behavior/async_presign.rs +175 -0
- data/core/tests/behavior/async_read.rs +871 -0
- data/core/tests/behavior/async_rename.rs +210 -0
- data/core/tests/behavior/async_stat.rs +628 -0
- data/core/tests/behavior/async_write.rs +819 -0
- data/core/tests/behavior/main.rs +78 -0
- data/core/tests/behavior/utils.rs +187 -0
- data/core/tests/data/normal_dir/.gitkeep +0 -0
- data/core/tests/data/normal_file.txt +1041 -0
- data/core/tests/data/special_dir !@#$%^&()_+-=;',/.gitkeep +0 -0
- data/core/tests/data/special_file !@#$%^&()_+-=;',.txt +1041 -0
- data/core/users.md +13 -0
- data/extconf.rb +24 -0
- data/lib/opendal.rb +25 -0
- data/lib/opendal_ruby/entry.rb +35 -0
- data/lib/opendal_ruby/io.rb +70 -0
- data/lib/opendal_ruby/metadata.rb +44 -0
- data/lib/opendal_ruby/operator.rb +29 -0
- data/lib/opendal_ruby/operator_info.rb +26 -0
- data/src/capability.rs +146 -0
- data/src/io.rs +464 -0
- data/src/lib.rs +63 -0
- data/src/lister.rs +141 -0
- data/src/metadata.rs +111 -0
- data/src/middlewares.rs +174 -0
- data/src/operator.rs +310 -0
- data/src/operator_info.rs +83 -0
- data/test/blocking_op_test.rb +112 -0
- data/test/capability_test.rb +42 -0
- data/test/io_test.rb +172 -0
- data/test/lister_test.rb +77 -0
- data/test/metadata_test.rb +78 -0
- data/test/middlewares_test.rb +46 -0
- data/test/operator_info_test.rb +35 -0
- data/test/test_helper.rb +36 -0
- metadata +857 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
- Proposal Name: `query_based_metadata`
|
|
2
|
+
- Start Date: 2022-02-22
|
|
3
|
+
- RFC PR: [apache/opendal#1398](https://github.com/apache/opendal/pull/1398)
|
|
4
|
+
- Tracking Issue: [apache/opendal#1398](https://github.com/apache/opendal/pull/1398)
|
|
5
|
+
|
|
6
|
+
# Summary
|
|
7
|
+
|
|
8
|
+
Read cached metadata based on users query.
|
|
9
|
+
|
|
10
|
+
# Motivation
|
|
11
|
+
|
|
12
|
+
OpenDAL has native metadata cache for now:
|
|
13
|
+
|
|
14
|
+
```rust
|
|
15
|
+
let _ = o.metadata().await?;
|
|
16
|
+
// This call doesn't need to send a request.
|
|
17
|
+
let _ = o.metadata().await?;
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Also, OpenDAL can reuse metadata from `list` or `scan`:
|
|
21
|
+
|
|
22
|
+
```rust
|
|
23
|
+
let mut ds = o.scan().await?;
|
|
24
|
+
while let Some(de) = ds.try_next().await? {
|
|
25
|
+
// This call doesn't need to send a request (if we are lucky enough).
|
|
26
|
+
let _ = de.metadata().await?;
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
By reusing metadata from `list` or `scan` we can reduce the extra `stat` call for each object. In our real use cases, we can reduce the total time to calculate the total length inside a dir with 6k files from 4 minutes to 2 seconds.
|
|
31
|
+
|
|
32
|
+
However, metadata can only be cached as a whole. If services could return more metadata in `stat` than in `list`, we wouldn't be able to mark the metadata as cacheable. If services add more metadata, we could inadvertently introduce the performance degradation.
|
|
33
|
+
|
|
34
|
+
RFC [Object Metadataer](./rfc_1391_object_metadataer) intends to add `ObjectMetadataer` to address this issue. But it sooner to be proved that a failure: it's hard to design a correct API.
|
|
35
|
+
|
|
36
|
+
Users have to write code like the following:
|
|
37
|
+
|
|
38
|
+
```rust
|
|
39
|
+
let om = o.metadata().await?;
|
|
40
|
+
let _ = om.content_length().await?;
|
|
41
|
+
let _ = om.content_md5().await?;
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
In this RFC, we will add a query based metadata.
|
|
45
|
+
|
|
46
|
+
# Guide-level explanation
|
|
47
|
+
|
|
48
|
+
After this RFC, `o.metadata()` will accept a query composed by `ObjectMetadataKey`.
|
|
49
|
+
|
|
50
|
+
To query already cached metadata:
|
|
51
|
+
|
|
52
|
+
```rust
|
|
53
|
+
let meta = op.object("test").metadata(None).await?;
|
|
54
|
+
let _ = meta.content_length();
|
|
55
|
+
let _ = meta.content_type();
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
To query content length and content type:
|
|
59
|
+
|
|
60
|
+
```rust
|
|
61
|
+
let meta = op
|
|
62
|
+
.object("test")
|
|
63
|
+
.metadata({
|
|
64
|
+
use ObjectMetadataKey::*;
|
|
65
|
+
ContentLength | ContentType
|
|
66
|
+
})
|
|
67
|
+
.await?;
|
|
68
|
+
let _ = meta.content_length();
|
|
69
|
+
let _ = meta.content_type();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
To query all metadata about this object:
|
|
73
|
+
|
|
74
|
+
```rust
|
|
75
|
+
let meta = op
|
|
76
|
+
.object("test")
|
|
77
|
+
.metadata({ ObjectMetadataKey::Complete })
|
|
78
|
+
.await?;
|
|
79
|
+
let _ = meta.content_length();
|
|
80
|
+
let _ = meta.content_type();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
# Reference-level explanation
|
|
84
|
+
|
|
85
|
+
We will store bits in `ObjectMetadata` to store which fields have been set. And we can compare the bits to decide whether we need to query from storage again:
|
|
86
|
+
|
|
87
|
+
```rust
|
|
88
|
+
pub async fn metadata(
|
|
89
|
+
&mut self,
|
|
90
|
+
flags: impl Into<FlagSet<ObjectMetadataKey>>,
|
|
91
|
+
) -> Result<Arc<ObjectMetadata>> {
|
|
92
|
+
if let Some(meta) = &self.meta {
|
|
93
|
+
if meta.bit().contains(flags) || meta.bit().contains(ObjectMetadataKey::Complete) {
|
|
94
|
+
return Ok(meta.clone());
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let meta = Arc::new(self.stat().await?);
|
|
99
|
+
self.meta = Some(meta.clone());
|
|
100
|
+
|
|
101
|
+
Ok(meta)
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
# Drawbacks
|
|
106
|
+
|
|
107
|
+
## Breaking changes
|
|
108
|
+
|
|
109
|
+
After this RFC, `Object::metadata()` will accept a query. And all existing users need to adapt their code for that.
|
|
110
|
+
|
|
111
|
+
# Rationale and alternatives
|
|
112
|
+
|
|
113
|
+
None
|
|
114
|
+
|
|
115
|
+
# Prior art
|
|
116
|
+
|
|
117
|
+
None
|
|
118
|
+
|
|
119
|
+
# Unresolved questions
|
|
120
|
+
|
|
121
|
+
None
|
|
122
|
+
|
|
123
|
+
# Future possibilities
|
|
124
|
+
|
|
125
|
+
None
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
- Proposal Name: `object_writer`
|
|
2
|
+
- Start Date: 2023-02-27
|
|
3
|
+
- RFC PR: [apache/opendal#1420](https://github.com/apache/opendal/pull/1420)
|
|
4
|
+
- Tracking Issue: [apache/opendal#1421](https://github.com/apache/opendal/issues/1421)
|
|
5
|
+
|
|
6
|
+
# Summary
|
|
7
|
+
|
|
8
|
+
Adding `ObjectWriter` to improve support for multipart uploads, as well as enable retry options for write operations.
|
|
9
|
+
|
|
10
|
+
# Motivation
|
|
11
|
+
|
|
12
|
+
OpenDAL works well for `read` operations:
|
|
13
|
+
|
|
14
|
+
- OpenDAL can seek over content even on services like S3.
|
|
15
|
+
- OpenDAL can retry read from the failing point without extra read cost.
|
|
16
|
+
|
|
17
|
+
However, OpenDAL is not good at `write`:
|
|
18
|
+
|
|
19
|
+
## Complex multipart operations
|
|
20
|
+
|
|
21
|
+
OpenDAL supports multipart operations but it's very hard to use:
|
|
22
|
+
|
|
23
|
+
```ignore
|
|
24
|
+
let object_multipart = o.create_multipart().await?;
|
|
25
|
+
let part_0 = object_multipart.write(0, content_0).await?;
|
|
26
|
+
...
|
|
27
|
+
let part_x = object_multipart.write(x, content_x).await?;
|
|
28
|
+
let new_object = object_multipart.complete(vec![part_0,...,part_x]).await?;
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Users should possess the knowledge of the multipart API to effectively use it.
|
|
32
|
+
|
|
33
|
+
To exacerbate the situation, the multipart API is not standardized and only some object storage services offer support for it. Unfortunately, we cannot even provide support for it on the local file system.
|
|
34
|
+
|
|
35
|
+
## Lack of retry support
|
|
36
|
+
|
|
37
|
+
OpenDAL can't retry `write` operations because we accept an `Box<dyn AsyncRead>`. Once we pass this read into other functions, we consumed it.
|
|
38
|
+
|
|
39
|
+
```rust
|
|
40
|
+
async fn write(&self, path: &str, args: OpWrite, r: input::Reader) -> Result<RpWrite> {
|
|
41
|
+
self.inner.write(path, args, r).await
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
By introducing the `ObjectWriter` feature, we anticipate resolving all the associated inquiries simultaneously.
|
|
46
|
+
|
|
47
|
+
# Guide-level explanation
|
|
48
|
+
|
|
49
|
+
`ObjectWriter` will provide the following APIs:
|
|
50
|
+
|
|
51
|
+
```rust
|
|
52
|
+
impl ObjectWriter {
|
|
53
|
+
pub async write(&mut self, bs: Bytes) -> Result<()>;
|
|
54
|
+
pub async close(&mut self) -> Result<()>;
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
After `ObjectWriter` has been constructed, users can use it as a normal writer:
|
|
59
|
+
|
|
60
|
+
```rust
|
|
61
|
+
let mut w = o.writer().await?;
|
|
62
|
+
w.write(bs1).await?;
|
|
63
|
+
w.write(bs2).await?;
|
|
64
|
+
w.close().await?;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`ObjectWriter` also implements `AsyncWrite` trait which will allow users to use `io::copy` as well:
|
|
68
|
+
|
|
69
|
+
```rust
|
|
70
|
+
let mut w = o.writer().await?;
|
|
71
|
+
let _ = io::copy_buf(r, o).await?;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
# Reference-level explanation
|
|
75
|
+
|
|
76
|
+
OpenDAL will add a new trait called `output::Writer`:
|
|
77
|
+
|
|
78
|
+
```rust
|
|
79
|
+
pub trait Write: Unpin + Send + Sync {
|
|
80
|
+
pub async write(&mut self, bs: Bytes) -> Result<()>;
|
|
81
|
+
|
|
82
|
+
pub async initiate(&mut self) -> Result<()>;
|
|
83
|
+
pub async append(&mut self, bs: Bytes) -> Result<()>;
|
|
84
|
+
|
|
85
|
+
pub async close(&mut self) -> Result<()>;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- `write` is used to write full content.
|
|
90
|
+
- `initiate` is used to initiate a multipart writer.
|
|
91
|
+
- `append` is used to append more content into this writer.
|
|
92
|
+
- `close` is used to close and construct the final file.
|
|
93
|
+
|
|
94
|
+
And `Accessor` will change the `write` API into:
|
|
95
|
+
|
|
96
|
+
```diff
|
|
97
|
+
pub trait Accessor {
|
|
98
|
+
+ type Writer: output::Write;
|
|
99
|
+
|
|
100
|
+
- async fn write(&self, path: &str, args: OpWrite, r: input::Reader) -> Result<RpWrite>;
|
|
101
|
+
+ async fn write(&self, path: &str, args: OpWrite) -> Result<(RpWrite, Self::Writer)>
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
# Drawbacks
|
|
106
|
+
|
|
107
|
+
More heavy work for service implementers.
|
|
108
|
+
|
|
109
|
+
# Rationale and alternatives
|
|
110
|
+
|
|
111
|
+
## Why accept `Bytes`?
|
|
112
|
+
|
|
113
|
+
OpenDAL's write is similar to `io::Write::write_all` which will always consume the whole input and return errors if something is wrong. By accepting `Bytes`, we can reduce the extra `Clone` between user land to OpenDAL's services/layers.
|
|
114
|
+
|
|
115
|
+
# Prior art
|
|
116
|
+
|
|
117
|
+
None.
|
|
118
|
+
|
|
119
|
+
# Unresolved questions
|
|
120
|
+
|
|
121
|
+
None.
|
|
122
|
+
|
|
123
|
+
# Future possibilities
|
|
124
|
+
|
|
125
|
+
## Vectored Write
|
|
126
|
+
|
|
127
|
+
We can add `write_vectored` support in the future:
|
|
128
|
+
|
|
129
|
+
```rust
|
|
130
|
+
pub trait Write: Unpin + Send + Sync {
|
|
131
|
+
pub async write_vectored(&mut self, bs: &[Bytes]) -> Result<()>;
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Take `s3` services as an example, we can upload different parts at the same time.
|
|
136
|
+
|
|
137
|
+
## Write From Stream
|
|
138
|
+
|
|
139
|
+
We can add `write_from` support in the future:
|
|
140
|
+
|
|
141
|
+
```rust
|
|
142
|
+
pub trait Write: Unpin + Send + Sync {
|
|
143
|
+
pub async write_from(&mut self, r: BytesStream, size: u64) -> Result<()>;
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
By implementing this feature, users don't need to hold a large buffer inside memory.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
- Proposal Name: `remove_object_concept`
|
|
2
|
+
- Start Date: `2023-03-05`
|
|
3
|
+
- RFC PR: [apache/opendal#1477](https://github.com/apache/opendal/pull/1477)
|
|
4
|
+
- Tracking Issue: [apache/opendal#0000](https://github.com/apache/opendal/issues/0000)
|
|
5
|
+
|
|
6
|
+
# Summary
|
|
7
|
+
|
|
8
|
+
Eliminating the Object concept to enhance the readability of OpenDAL.
|
|
9
|
+
|
|
10
|
+
# Motivation
|
|
11
|
+
|
|
12
|
+
OpenDAL introduces [Object Native API][crate::docs::rfcs::rfc_0041_object_native_api] to resolve the problem of not being easy to use:
|
|
13
|
+
|
|
14
|
+
```diff
|
|
15
|
+
- let reader = SeekableReader::new(op, path, stream_len);
|
|
16
|
+
+ let reader = op.object(&path).reader().await?;
|
|
17
|
+
|
|
18
|
+
- op.stat(&path).run().await
|
|
19
|
+
+ op.object(&path).stat().await
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
However, times are changing. After the list operation has been moved to the `Object` level, `Object` is now more like a wrapper for `Operator`. The only meaningful API of `Operator` now is `Operator::object`.
|
|
23
|
+
|
|
24
|
+
Writing `op.object(&path)` repeatedly is boring. Let's take real example from databend as an example:
|
|
25
|
+
|
|
26
|
+
```rust
|
|
27
|
+
if let Some(dir) = dir_path {
|
|
28
|
+
match op.object(&dir).stat().await {
|
|
29
|
+
Ok(_) => {
|
|
30
|
+
let mut ds = op.object(&dir).scan().await?;
|
|
31
|
+
while let Some(de) = ds.try_next().await? {
|
|
32
|
+
if let Some(fi) = stat_file(de).await? {
|
|
33
|
+
files.push(fi)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
Err(e) => warn!("ignore listing {path}/, because: {:?}", e),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
We designed `Object` to make users can reuse the same `Object`. However, nearly no users use our API this way. Most users just build a new `Object` every time. There are two problems:
|
|
43
|
+
|
|
44
|
+
## Extra cost
|
|
45
|
+
|
|
46
|
+
`Object::new()` is not zero cost:
|
|
47
|
+
|
|
48
|
+
```rust
|
|
49
|
+
pub(crate) fn with(op: Operator, path: &str, meta: Option<ObjectMetadata>) -> Self {
|
|
50
|
+
Self {
|
|
51
|
+
acc: op.inner(),
|
|
52
|
+
path: Arc::new(normalize_path(path)),
|
|
53
|
+
meta: meta.map(Arc::new),
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The `Object` must contain an `Operator` and an `Arc` of strings. With the introduction of [Query Based Metadata][crate::docs::rfcs::rfc_1398_query_based_metadata], there is no longer a need to perform operations on the object.
|
|
59
|
+
|
|
60
|
+
## Complex concepts
|
|
61
|
+
|
|
62
|
+
The term `Object` is applied in various fields, making it difficult to provide a concise definition of `opendal::Object`. Moreover, this could potentially confuse our users who may assume that `opendal::Object` is primarily intended for object storage services.
|
|
63
|
+
|
|
64
|
+
I propose eliminating the intermediate API layer of `Object` and enabling users to directly utilize `Operator`.
|
|
65
|
+
|
|
66
|
+
# Guide-level explanation
|
|
67
|
+
|
|
68
|
+
After this RFC is implemented, our users can:
|
|
69
|
+
|
|
70
|
+
```rust
|
|
71
|
+
# read all content of the file
|
|
72
|
+
op.read("file").await?;
|
|
73
|
+
# read part content of the file
|
|
74
|
+
op.range_read("file", 0..1024).await?;
|
|
75
|
+
# create a reader
|
|
76
|
+
op.reader("file").await?;
|
|
77
|
+
|
|
78
|
+
# write all content into file
|
|
79
|
+
op.write("file", bs).await?;
|
|
80
|
+
# create a writer
|
|
81
|
+
op.writer("file").await?;
|
|
82
|
+
|
|
83
|
+
# get metadata of a path
|
|
84
|
+
op.stat("path").await?;
|
|
85
|
+
|
|
86
|
+
# delete a path
|
|
87
|
+
op.delete("path").await?;
|
|
88
|
+
# remove paths
|
|
89
|
+
op.remove(vec!["path_a"]).await?;
|
|
90
|
+
# remove path recursively
|
|
91
|
+
op.remove_all("path").await?;
|
|
92
|
+
|
|
93
|
+
# create a dir
|
|
94
|
+
op.create_dir("dir/").await?;
|
|
95
|
+
|
|
96
|
+
# list a dir
|
|
97
|
+
op.list("dir/").await?;
|
|
98
|
+
# scan a dir
|
|
99
|
+
op.scan("dir/").await?;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
We will include the `blocking::Operator` for enhanced ease of use while performing blocking operations.
|
|
103
|
+
|
|
104
|
+
```rust
|
|
105
|
+
# this is a cheap call without allocation
|
|
106
|
+
let bop = op.blocking();
|
|
107
|
+
|
|
108
|
+
# read all content
|
|
109
|
+
bop.read("file")?;
|
|
110
|
+
# write all content
|
|
111
|
+
bop.write("file", bs)?;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The scan/list result will be an `Entry` or `BlockingEntry` that contains the same fields as Object, but is only used for scan/list entries.
|
|
115
|
+
|
|
116
|
+
The public API should look like:
|
|
117
|
+
|
|
118
|
+
```rust
|
|
119
|
+
impl Entry {
|
|
120
|
+
pub fn mode(&self) -> EntryType;
|
|
121
|
+
pub fn path(&self) -> &str;
|
|
122
|
+
pub async fn stat(&self) -> Result<Metadata>;
|
|
123
|
+
pub async fn metadata(&self, key: impl Into<MetaKey>) -> Result<Metadata>;
|
|
124
|
+
...
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
# Reference-level explanation
|
|
129
|
+
|
|
130
|
+
We will remove `Object` entirely and move all `Object` APIs to `Operator` instead:
|
|
131
|
+
|
|
132
|
+
```rust
|
|
133
|
+
- op.object("path").read().await
|
|
134
|
+
+ op.read("path").await
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Along with this change, we should also rename the `ObjectXxx` structs, such as `ObjectReader` to `Reader`.
|
|
138
|
+
|
|
139
|
+
# Drawbacks
|
|
140
|
+
|
|
141
|
+
## Breaking Changes
|
|
142
|
+
|
|
143
|
+
This RFC proposes a major breaking change that will require almost all current usage to be rewritten.
|
|
144
|
+
|
|
145
|
+
# Rationale and alternatives
|
|
146
|
+
|
|
147
|
+
None
|
|
148
|
+
|
|
149
|
+
# Prior art
|
|
150
|
+
|
|
151
|
+
None
|
|
152
|
+
|
|
153
|
+
# Unresolved questions
|
|
154
|
+
|
|
155
|
+
None
|
|
156
|
+
|
|
157
|
+
# Future possibilities
|
|
158
|
+
|
|
159
|
+
None
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
- Proposal Name: `operation_extension`
|
|
2
|
+
- Start Date: 2023-03-23
|
|
3
|
+
- RFC PR: [apache/opendal#1735](https://github.com/apache/opendal/pull/1735)
|
|
4
|
+
- Tracking Issue: [apache/opendal#1738](https://github.com/apache/opendal/issues/1738)
|
|
5
|
+
|
|
6
|
+
# Summary
|
|
7
|
+
|
|
8
|
+
Extend operation capabilities to support additional native features.
|
|
9
|
+
|
|
10
|
+
# Motivation
|
|
11
|
+
|
|
12
|
+
OpenDAL only supports a limited set of capabilities for operations.
|
|
13
|
+
|
|
14
|
+
- `read`/`stat`: only supports `range`
|
|
15
|
+
- `write`: only supports `content_type` and `content_disposition`
|
|
16
|
+
|
|
17
|
+
Our community has a strong need for more additional native features. For example:
|
|
18
|
+
|
|
19
|
+
- [opendal#892](https://github.com/apache/opendal/issues/892) wants [Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control): Allow users to specify the cache control headers for the uploaded files.
|
|
20
|
+
- [opendal#825](https://github.com/apache/opendal/issues/825) wants [If-Match](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Match) and [If-None-Match](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match): Allow users to makes a request conditional.
|
|
21
|
+
- [opendal#1726](https://github.com/apache/opendal/issues/1726) wants [response-content-disposition](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html): Allow users to specify the content disposition for the downloaded files.
|
|
22
|
+
|
|
23
|
+
All of these feature requests are essentially asking for the same thing: the capability to define supplementary arguments for operations, particularly about HTTP services.
|
|
24
|
+
|
|
25
|
+
# Guide-level explanation
|
|
26
|
+
|
|
27
|
+
In this RFC, we will allow users to specify the standard HTTP headers like cache_control/if_match:
|
|
28
|
+
|
|
29
|
+
```rust
|
|
30
|
+
let op = OpRead::default().
|
|
31
|
+
with_cache_control("max-age=3600").
|
|
32
|
+
with_if_match("\"bfc13a64729c4290ef5b2c2730249c88ca92d82d\"");
|
|
33
|
+
let bs = o.read_with(op).await?;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Also, we will support some non-standard but widely used features like `response-content-disposition`:
|
|
37
|
+
|
|
38
|
+
```rust
|
|
39
|
+
let op = OpRead::default().
|
|
40
|
+
with_override_content_disposition("attachment; filename=\"foo.txt\"");
|
|
41
|
+
let req = op.presign_read_with("filename", Duration::hours(1), op)?;
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
And, finally, we will support allow specify the default headers for services. Take `s3`'s `storage_class` as an example:
|
|
45
|
+
|
|
46
|
+
```rust
|
|
47
|
+
let mut builder = S3::default();
|
|
48
|
+
builder.default_storage_class("STANDARD_IA");
|
|
49
|
+
builder.default_cache_control("max-age=3600");
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
In general, we will support the following features:
|
|
53
|
+
|
|
54
|
+
- Allow users to specify the (non-)standard HTTP headers for operations.
|
|
55
|
+
- Allow users to specify the default HTTP headers for services.
|
|
56
|
+
|
|
57
|
+
# Reference-level explanation
|
|
58
|
+
|
|
59
|
+
We will make the following changes in OpenDAL:
|
|
60
|
+
|
|
61
|
+
For `OpRead` & `OpStat`:
|
|
62
|
+
|
|
63
|
+
```diff
|
|
64
|
+
pub struct OpRead {
|
|
65
|
+
br: BytesRange,
|
|
66
|
+
+ cache_control: Option<String>,
|
|
67
|
+
+ if_match: Option<String>,
|
|
68
|
+
+ if_none_match: Option<String>,
|
|
69
|
+
+ override_content_disposition: Option<String>,
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
For `OpWrite`:
|
|
74
|
+
|
|
75
|
+
```diff
|
|
76
|
+
pub struct OpWrite {
|
|
77
|
+
append: bool,
|
|
78
|
+
|
|
79
|
+
content_type: Option<String>,
|
|
80
|
+
content_disposition: Option<String>,
|
|
81
|
+
+ cache_control: Option<String>,
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
We will provide different default options for each service. For example, we can add `default_storage_class` for `s3`.
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# Drawbacks
|
|
89
|
+
|
|
90
|
+
None
|
|
91
|
+
|
|
92
|
+
# Rationale and alternatives
|
|
93
|
+
|
|
94
|
+
## Why using `override_content_disposition` instead of `response_content_disposition`?
|
|
95
|
+
|
|
96
|
+
`response_content_disposition` is not a part of HTTP standard, it's the private API provided by `s3`.
|
|
97
|
+
|
|
98
|
+
- `azblob` will use `x-ms-blob-content-disposition` header
|
|
99
|
+
- `ocios` will use `httpResponseContentDisposition` query
|
|
100
|
+
|
|
101
|
+
OpenDAL does not accept the query as is. Instead, we have created a more readable name `override_content_disposition` to clarify its purpose.
|
|
102
|
+
|
|
103
|
+
# Prior art
|
|
104
|
+
|
|
105
|
+
None
|
|
106
|
+
|
|
107
|
+
# Unresolved questions
|
|
108
|
+
|
|
109
|
+
None
|
|
110
|
+
|
|
111
|
+
# Future possibilities
|
|
112
|
+
|
|
113
|
+
## Strict Mode
|
|
114
|
+
|
|
115
|
+
Additionally, we have implemented a `strict` option for the `Operator`. If users enable this option, OpenDAL will return an error message for unsupported options. Otherwise, it will ignore them.
|
|
116
|
+
|
|
117
|
+
For instance, if users rely on the `if_match` behavior but services like `fs` and `hdfs` do not support it natively, they can use the `op.with_strict()` function to prompt OpenDAL to return an error.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
- Proposal Name: `writer_sink_api`
|
|
2
|
+
- Start Date: 2023-04-23
|
|
3
|
+
- RFC PR: [apache/opendal#2083](https://github.com/apache/opendal/pull/2083)
|
|
4
|
+
- Tracking Issue: [apache/opendal#2084](https://github.com/apache/opendal/issues/2084)
|
|
5
|
+
|
|
6
|
+
# Summary
|
|
7
|
+
|
|
8
|
+
Include a `sink` API within the `Writer` to enable streaming writing.
|
|
9
|
+
|
|
10
|
+
# Motivation
|
|
11
|
+
|
|
12
|
+
OpenDAL does not support streaming data uploads. Users must first load the data into memory and then send it to the `writer`.
|
|
13
|
+
|
|
14
|
+
```rust
|
|
15
|
+
let bs = balabala();
|
|
16
|
+
w.write(bs).await?;
|
|
17
|
+
let bs = daladala();
|
|
18
|
+
w.write(bs).await?;
|
|
19
|
+
...
|
|
20
|
+
w.close().await?;
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
There are two main drawbacks to OpenDAL:
|
|
24
|
+
|
|
25
|
+
- high memory usage, as reported in issue #1821 on GitHub
|
|
26
|
+
- low performance due to the need to buffer user data before sending it over the network.
|
|
27
|
+
|
|
28
|
+
To address this issue, it would be beneficial for OpenDAL to provide an API that allows users to pass a stream or reader directly into the writer.
|
|
29
|
+
|
|
30
|
+
# Guide-level explanation
|
|
31
|
+
|
|
32
|
+
I propose to add the following API to `Writer`:
|
|
33
|
+
|
|
34
|
+
```rust
|
|
35
|
+
impl Writer {
|
|
36
|
+
pub async fn copy_from<R>(&mut self, size: u64, r: R) -> Result<()>
|
|
37
|
+
where
|
|
38
|
+
R: futures::AsyncRead + Send + Sync + 'static;
|
|
39
|
+
|
|
40
|
+
pub async fn pipe_from<S>(&mut self, size: u64, s: S) -> Result<()>
|
|
41
|
+
where
|
|
42
|
+
S: futures::TryStream + Send + Sync + 'static
|
|
43
|
+
Bytes: From<S::Ok>;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Users can now upload data in a streaming way:
|
|
48
|
+
|
|
49
|
+
```rust
|
|
50
|
+
// Start writing the 5 TiB file.
|
|
51
|
+
let w = op.writer_with(
|
|
52
|
+
OpWrite::default()
|
|
53
|
+
.with_content_length(5 * 1024 * 1024 * 1024 * 1024));
|
|
54
|
+
|
|
55
|
+
let r = balabala();
|
|
56
|
+
// Send to network directly without in-memory buffer.
|
|
57
|
+
w.copy_from(size, r).await?;
|
|
58
|
+
// repeat...
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
// Close the write once we are ready!
|
|
62
|
+
w.close().await?;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The underlying services will handle this stream in the most efficient way possible.
|
|
66
|
+
|
|
67
|
+
# Reference-level explanation
|
|
68
|
+
|
|
69
|
+
To support `Wrtier::copy_from` and `Writer::pipe_from`, we will add a new API called `sink` inside `oio::Writer`:
|
|
70
|
+
|
|
71
|
+
```rust
|
|
72
|
+
#[async_trait]
|
|
73
|
+
pub trait Write: Unpin + Send + Sync {
|
|
74
|
+
async fn sink(&mut self, size: u64, s: Box<dyn futures::TryStream<Ok=Bytes> + Send + Sync>) -> Result<()>;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
OpenDAL converts the user input reader and stream into a byte stream for `oio::Write`. Services that support streaming upload natively can directly pass the stream. If not, they can use `write` repeatedly to write the entire stream.
|
|
79
|
+
|
|
80
|
+
# Drawbacks
|
|
81
|
+
|
|
82
|
+
None.
|
|
83
|
+
|
|
84
|
+
# Rationale and alternatives
|
|
85
|
+
|
|
86
|
+
## What's the different of `OpWrite::content_length` and `sink` size?
|
|
87
|
+
|
|
88
|
+
The `OpWrite::content_length` parameter specifies the total length of the file to be written, while the `size` argument in the `sink` API indicates the size of the reader or stream provided. Certain services may optimize by writing all content in a single request if `content_length` is the same with given `size`.
|
|
89
|
+
|
|
90
|
+
# Prior art
|
|
91
|
+
|
|
92
|
+
None
|
|
93
|
+
|
|
94
|
+
# Unresolved questions
|
|
95
|
+
|
|
96
|
+
None
|
|
97
|
+
|
|
98
|
+
# Future possibilities
|
|
99
|
+
|
|
100
|
+
## Retry for the `sink` API
|
|
101
|
+
|
|
102
|
+
It's impossible to retry the `sink` API itself, but we can provide a wrapper to retry the stream's call of `next`. If we met a retryable error, we can call `next` again by crate like `backon`.
|
|
103
|
+
|
|
104
|
+
## Blocking support for sink
|
|
105
|
+
|
|
106
|
+
We will add async support first.
|