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,201 @@
|
|
|
1
|
+
// Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
// or more contributor license agreements. See the NOTICE file
|
|
3
|
+
// distributed with this work for additional information
|
|
4
|
+
// regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
// to you under the Apache License, Version 2.0 (the
|
|
6
|
+
// "License"); you may not use this file except in compliance
|
|
7
|
+
// with the License. You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing,
|
|
12
|
+
// software distributed under the License is distributed on an
|
|
13
|
+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
// KIND, either express or implied. See the License for the
|
|
15
|
+
// specific language governing permissions and limitations
|
|
16
|
+
// under the License.
|
|
17
|
+
|
|
18
|
+
//! [`type_alias_impl_trait`](https://github.com/rust-lang/rust/issues/63063) is not stable yet.
|
|
19
|
+
//! So we can't write the following code:
|
|
20
|
+
//!
|
|
21
|
+
//! ```txt
|
|
22
|
+
//! impl Access for S3Backend {
|
|
23
|
+
//! type Writer = impl oio::Write;
|
|
24
|
+
//! }
|
|
25
|
+
//! ```
|
|
26
|
+
//!
|
|
27
|
+
//! Which means we have to write the type directly like:
|
|
28
|
+
//!
|
|
29
|
+
//! ```txt
|
|
30
|
+
//! impl Access for OssBackend {
|
|
31
|
+
//! type Writer = raw::TwoWays<
|
|
32
|
+
//! oio::MultipartWriter<OssWriter>,
|
|
33
|
+
//! oio::AppendWriter<OssWriter>,
|
|
34
|
+
//! >;
|
|
35
|
+
//! }
|
|
36
|
+
//! ```
|
|
37
|
+
//!
|
|
38
|
+
//! This module is used to provide some enums for the above code. We should remove this module once
|
|
39
|
+
//! type_alias_impl_trait has been stabilized.
|
|
40
|
+
|
|
41
|
+
use crate::raw::*;
|
|
42
|
+
use crate::*;
|
|
43
|
+
|
|
44
|
+
/// TwoWays is used to implement traits that based on two ways.
|
|
45
|
+
///
|
|
46
|
+
/// Users can wrap two different trait types together.
|
|
47
|
+
pub enum TwoWays<ONE, TWO> {
|
|
48
|
+
/// The first type for the [`TwoWays`].
|
|
49
|
+
One(ONE),
|
|
50
|
+
/// The second type for the [`TwoWays`].
|
|
51
|
+
Two(TWO),
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
impl<ONE: oio::Read, TWO: oio::Read> oio::Read for TwoWays<ONE, TWO> {
|
|
55
|
+
async fn read(&mut self) -> Result<Buffer> {
|
|
56
|
+
match self {
|
|
57
|
+
TwoWays::One(v) => v.read().await,
|
|
58
|
+
TwoWays::Two(v) => v.read().await,
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
impl<ONE: oio::Write, TWO: oio::Write> oio::Write for TwoWays<ONE, TWO> {
|
|
64
|
+
async fn write(&mut self, bs: Buffer) -> Result<()> {
|
|
65
|
+
match self {
|
|
66
|
+
Self::One(v) => v.write(bs).await,
|
|
67
|
+
Self::Two(v) => v.write(bs).await,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async fn close(&mut self) -> Result<Metadata> {
|
|
72
|
+
match self {
|
|
73
|
+
Self::One(v) => v.close().await,
|
|
74
|
+
Self::Two(v) => v.close().await,
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async fn abort(&mut self) -> Result<()> {
|
|
79
|
+
match self {
|
|
80
|
+
Self::One(v) => v.abort().await,
|
|
81
|
+
Self::Two(v) => v.abort().await,
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
impl<ONE: oio::List, TWO: oio::List> oio::List for TwoWays<ONE, TWO> {
|
|
87
|
+
async fn next(&mut self) -> Result<Option<oio::Entry>> {
|
|
88
|
+
match self {
|
|
89
|
+
Self::One(v) => v.next().await,
|
|
90
|
+
Self::Two(v) => v.next().await,
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/// ThreeWays is used to implement traits that based on three ways.
|
|
96
|
+
///
|
|
97
|
+
/// Users can wrap three different trait types together.
|
|
98
|
+
pub enum ThreeWays<ONE, TWO, THREE> {
|
|
99
|
+
/// The first type for the [`ThreeWays`].
|
|
100
|
+
One(ONE),
|
|
101
|
+
/// The second type for the [`ThreeWays`].
|
|
102
|
+
Two(TWO),
|
|
103
|
+
/// The third type for the [`ThreeWays`].
|
|
104
|
+
Three(THREE),
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
impl<ONE: oio::Read, TWO: oio::Read, THREE: oio::Read> oio::Read for ThreeWays<ONE, TWO, THREE> {
|
|
108
|
+
async fn read(&mut self) -> Result<Buffer> {
|
|
109
|
+
match self {
|
|
110
|
+
ThreeWays::One(v) => v.read().await,
|
|
111
|
+
ThreeWays::Two(v) => v.read().await,
|
|
112
|
+
ThreeWays::Three(v) => v.read().await,
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
impl<ONE: oio::Write, TWO: oio::Write, THREE: oio::Write> oio::Write
|
|
118
|
+
for ThreeWays<ONE, TWO, THREE>
|
|
119
|
+
{
|
|
120
|
+
async fn write(&mut self, bs: Buffer) -> Result<()> {
|
|
121
|
+
match self {
|
|
122
|
+
Self::One(v) => v.write(bs).await,
|
|
123
|
+
Self::Two(v) => v.write(bs).await,
|
|
124
|
+
Self::Three(v) => v.write(bs).await,
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async fn close(&mut self) -> Result<Metadata> {
|
|
129
|
+
match self {
|
|
130
|
+
Self::One(v) => v.close().await,
|
|
131
|
+
Self::Two(v) => v.close().await,
|
|
132
|
+
Self::Three(v) => v.close().await,
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async fn abort(&mut self) -> Result<()> {
|
|
137
|
+
match self {
|
|
138
|
+
Self::One(v) => v.abort().await,
|
|
139
|
+
Self::Two(v) => v.abort().await,
|
|
140
|
+
Self::Three(v) => v.abort().await,
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
impl<ONE: oio::List, TWO: oio::List, THREE: oio::List> oio::List for ThreeWays<ONE, TWO, THREE> {
|
|
146
|
+
async fn next(&mut self) -> Result<Option<oio::Entry>> {
|
|
147
|
+
match self {
|
|
148
|
+
Self::One(v) => v.next().await,
|
|
149
|
+
Self::Two(v) => v.next().await,
|
|
150
|
+
Self::Three(v) => v.next().await,
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// FourWays is used to implement traits that based on four ways.
|
|
156
|
+
///
|
|
157
|
+
/// Users can wrap four different trait types together.
|
|
158
|
+
pub enum FourWays<ONE, TWO, THREE, FOUR> {
|
|
159
|
+
/// The first type for the [`FourWays`].
|
|
160
|
+
One(ONE),
|
|
161
|
+
/// The second type for the [`FourWays`].
|
|
162
|
+
Two(TWO),
|
|
163
|
+
/// The third type for the [`FourWays`].
|
|
164
|
+
Three(THREE),
|
|
165
|
+
/// The fourth type for the [`FourWays`].
|
|
166
|
+
Four(FOUR),
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
impl<ONE, TWO, THREE, FOUR> oio::Read for FourWays<ONE, TWO, THREE, FOUR>
|
|
170
|
+
where
|
|
171
|
+
ONE: oio::Read,
|
|
172
|
+
TWO: oio::Read,
|
|
173
|
+
THREE: oio::Read,
|
|
174
|
+
FOUR: oio::Read,
|
|
175
|
+
{
|
|
176
|
+
async fn read(&mut self) -> Result<Buffer> {
|
|
177
|
+
match self {
|
|
178
|
+
FourWays::One(v) => v.read().await,
|
|
179
|
+
FourWays::Two(v) => v.read().await,
|
|
180
|
+
FourWays::Three(v) => v.read().await,
|
|
181
|
+
FourWays::Four(v) => v.read().await,
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
impl<ONE, TWO, THREE, FOUR> oio::List for FourWays<ONE, TWO, THREE, FOUR>
|
|
187
|
+
where
|
|
188
|
+
ONE: oio::List,
|
|
189
|
+
TWO: oio::List,
|
|
190
|
+
THREE: oio::List,
|
|
191
|
+
FOUR: oio::List,
|
|
192
|
+
{
|
|
193
|
+
async fn next(&mut self) -> Result<Option<oio::Entry>> {
|
|
194
|
+
match self {
|
|
195
|
+
Self::One(v) => v.next().await,
|
|
196
|
+
Self::Two(v) => v.next().await,
|
|
197
|
+
Self::Three(v) => v.next().await,
|
|
198
|
+
Self::Four(v) => v.next().await,
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
// Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
// or more contributor license agreements. See the NOTICE file
|
|
3
|
+
// distributed with this work for additional information
|
|
4
|
+
// regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
// to you under the Apache License, Version 2.0 (the
|
|
6
|
+
// "License"); you may not use this file except in compliance
|
|
7
|
+
// with the License. You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing,
|
|
12
|
+
// software distributed under the License is distributed on an
|
|
13
|
+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
// KIND, either express or implied. See the License for the
|
|
15
|
+
// specific language governing permissions and limitations
|
|
16
|
+
// under the License.
|
|
17
|
+
|
|
18
|
+
use std::collections::VecDeque;
|
|
19
|
+
use std::sync::atomic::AtomicUsize;
|
|
20
|
+
use std::sync::atomic::Ordering;
|
|
21
|
+
use std::sync::Arc;
|
|
22
|
+
|
|
23
|
+
use futures::FutureExt;
|
|
24
|
+
|
|
25
|
+
use crate::*;
|
|
26
|
+
|
|
27
|
+
/// BoxedFuture is the type alias of [`futures::future::BoxFuture`].
|
|
28
|
+
#[cfg(not(target_arch = "wasm32"))]
|
|
29
|
+
pub type BoxedFuture<'a, T> = futures::future::BoxFuture<'a, T>;
|
|
30
|
+
#[cfg(target_arch = "wasm32")]
|
|
31
|
+
/// BoxedFuture is the type alias of [`futures::future::LocalBoxFuture`].
|
|
32
|
+
pub type BoxedFuture<'a, T> = futures::future::LocalBoxFuture<'a, T>;
|
|
33
|
+
|
|
34
|
+
/// BoxedStaticFuture is the type alias of [`futures::future::BoxFuture`].
|
|
35
|
+
#[cfg(not(target_arch = "wasm32"))]
|
|
36
|
+
pub type BoxedStaticFuture<T> = futures::future::BoxFuture<'static, T>;
|
|
37
|
+
#[cfg(target_arch = "wasm32")]
|
|
38
|
+
/// BoxedStaticFuture is the type alias of [`futures::future::LocalBoxFuture`].
|
|
39
|
+
pub type BoxedStaticFuture<T> = futures::future::LocalBoxFuture<'static, T>;
|
|
40
|
+
|
|
41
|
+
/// MaybeSend is a marker to determine whether a type is `Send` or not.
|
|
42
|
+
/// We use this trait to wrap the `Send` requirement for wasm32 target.
|
|
43
|
+
///
|
|
44
|
+
/// # Safety
|
|
45
|
+
///
|
|
46
|
+
/// [`MaybeSend`] is equivalent to `Send` on non-wasm32 target.
|
|
47
|
+
/// And it's empty trait on wasm32 target to indicate that a type is not `Send`.
|
|
48
|
+
#[cfg(not(target_arch = "wasm32"))]
|
|
49
|
+
pub trait MaybeSend: Send {}
|
|
50
|
+
|
|
51
|
+
/// MaybeSend is a marker to determine whether a type is `Send` or not.
|
|
52
|
+
/// We use this trait to wrap the `Send` requirement for wasm32 target.
|
|
53
|
+
///
|
|
54
|
+
/// # Safety
|
|
55
|
+
///
|
|
56
|
+
/// [`MaybeSend`] is equivalent to `Send` on non-wasm32 target.
|
|
57
|
+
/// And it's empty trait on wasm32 target to indicate that a type is not `Send`.
|
|
58
|
+
#[cfg(target_arch = "wasm32")]
|
|
59
|
+
pub trait MaybeSend {}
|
|
60
|
+
|
|
61
|
+
#[cfg(not(target_arch = "wasm32"))]
|
|
62
|
+
impl<T: Send> MaybeSend for T {}
|
|
63
|
+
#[cfg(target_arch = "wasm32")]
|
|
64
|
+
impl<T> MaybeSend for T {}
|
|
65
|
+
|
|
66
|
+
/// ConcurrentTasks is used to execute tasks concurrently.
|
|
67
|
+
///
|
|
68
|
+
/// ConcurrentTasks has two generic types:
|
|
69
|
+
///
|
|
70
|
+
/// - `I` represents the input type of the task.
|
|
71
|
+
/// - `O` represents the output type of the task.
|
|
72
|
+
///
|
|
73
|
+
/// # Implementation Notes
|
|
74
|
+
///
|
|
75
|
+
/// The code patterns below are intentional; please do not modify them unless you fully understand these notes.
|
|
76
|
+
///
|
|
77
|
+
/// ```skip
|
|
78
|
+
/// let (i, o) = self
|
|
79
|
+
/// .tasks
|
|
80
|
+
/// .front_mut() // Use `front_mut` instead of `pop_front`
|
|
81
|
+
/// .expect("tasks must be available")
|
|
82
|
+
/// .await;
|
|
83
|
+
/// ...
|
|
84
|
+
/// match o {
|
|
85
|
+
/// Ok(o) => {
|
|
86
|
+
/// let _ = self.tasks.pop_front(); // `pop_front` after got `Ok(o)`
|
|
87
|
+
/// self.results.push_back(o)
|
|
88
|
+
/// }
|
|
89
|
+
/// Err(err) => {
|
|
90
|
+
/// if err.is_temporary() {
|
|
91
|
+
/// let task = self.create_task(i);
|
|
92
|
+
/// self.tasks
|
|
93
|
+
/// .front_mut()
|
|
94
|
+
/// .expect("tasks must be available")
|
|
95
|
+
/// .replace(task) // Use replace here to instead of `push_front`
|
|
96
|
+
/// } else {
|
|
97
|
+
/// self.clear();
|
|
98
|
+
/// self.errored = true;
|
|
99
|
+
/// }
|
|
100
|
+
/// return Err(err);
|
|
101
|
+
/// }
|
|
102
|
+
/// }
|
|
103
|
+
/// ```
|
|
104
|
+
///
|
|
105
|
+
/// Please keep in mind that there is no guarantee the task will be `await`ed until completion. It's possible
|
|
106
|
+
/// the task may be dropped before it resolves. Therefore, we should keep the `Task` in the `tasks` queue until
|
|
107
|
+
/// it is resolved.
|
|
108
|
+
///
|
|
109
|
+
/// For example, users may have a timeout for the task, and the task will be dropped if it exceeds the timeout.
|
|
110
|
+
/// If we `pop_front` the task before it resolves, the task will be canceled and the result will be lost.
|
|
111
|
+
pub struct ConcurrentTasks<I, O> {
|
|
112
|
+
/// The executor to execute the tasks.
|
|
113
|
+
///
|
|
114
|
+
/// If user doesn't provide an executor, the tasks will be executed with the default executor.
|
|
115
|
+
executor: Executor,
|
|
116
|
+
/// The factory to create the task.
|
|
117
|
+
///
|
|
118
|
+
/// Caller of ConcurrentTasks must provides a factory to create the task for executing.
|
|
119
|
+
///
|
|
120
|
+
/// The factory must accept an input and return a future that resolves to a tuple of input and
|
|
121
|
+
/// output result. If the given result is error, the error will be returned to users and the
|
|
122
|
+
/// task will be retried.
|
|
123
|
+
factory: fn(I) -> BoxedStaticFuture<(I, Result<O>)>,
|
|
124
|
+
|
|
125
|
+
/// `tasks` holds the ongoing tasks.
|
|
126
|
+
///
|
|
127
|
+
/// Please keep in mind that all tasks are running in the background by `Executor`. We only need
|
|
128
|
+
/// to poll the tasks to see if they are ready.
|
|
129
|
+
///
|
|
130
|
+
/// Dropping task without `await` it will cancel the task.
|
|
131
|
+
tasks: VecDeque<Task<(I, Result<O>)>>,
|
|
132
|
+
/// `results` stores the successful results.
|
|
133
|
+
results: VecDeque<O>,
|
|
134
|
+
|
|
135
|
+
/// The maximum number of concurrent tasks.
|
|
136
|
+
concurrent: usize,
|
|
137
|
+
/// The maximum number of completed tasks that can be buffered.
|
|
138
|
+
prefetch: usize,
|
|
139
|
+
/// Tracks the number of tasks that have finished execution but have not yet been collected.
|
|
140
|
+
/// This count is subtracted from the total concurrency capacity, ensuring that the system
|
|
141
|
+
/// always schedules new tasks to maintain the user's desired concurrency level.
|
|
142
|
+
///
|
|
143
|
+
/// Example: If `concurrency = 10` and `completed_but_unretrieved = 3`,
|
|
144
|
+
/// the system can still spawn 7 new tasks (since 3 slots are "logically occupied"
|
|
145
|
+
/// by uncollected results).
|
|
146
|
+
completed_but_unretrieved: Arc<AtomicUsize>,
|
|
147
|
+
/// hitting the last unrecoverable error.
|
|
148
|
+
///
|
|
149
|
+
/// If concurrent tasks hit an unrecoverable error, it will stop executing new tasks and return
|
|
150
|
+
/// an unrecoverable error to users.
|
|
151
|
+
errored: bool,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
impl<I: Send + 'static, O: Send + 'static> ConcurrentTasks<I, O> {
|
|
155
|
+
/// Create a new concurrent tasks with given executor, concurrent, prefetch and factory.
|
|
156
|
+
///
|
|
157
|
+
/// The factory is a function pointer that shouldn't capture any context.
|
|
158
|
+
pub fn new(
|
|
159
|
+
executor: Executor,
|
|
160
|
+
concurrent: usize,
|
|
161
|
+
prefetch: usize,
|
|
162
|
+
factory: fn(I) -> BoxedStaticFuture<(I, Result<O>)>,
|
|
163
|
+
) -> Self {
|
|
164
|
+
Self {
|
|
165
|
+
executor,
|
|
166
|
+
factory,
|
|
167
|
+
|
|
168
|
+
tasks: VecDeque::with_capacity(concurrent),
|
|
169
|
+
results: VecDeque::with_capacity(concurrent),
|
|
170
|
+
concurrent,
|
|
171
|
+
prefetch,
|
|
172
|
+
completed_but_unretrieved: Arc::default(),
|
|
173
|
+
errored: false,
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/// Return true if the tasks are running concurrently.
|
|
178
|
+
#[inline]
|
|
179
|
+
fn is_concurrent(&self) -> bool {
|
|
180
|
+
self.concurrent > 1
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/// Clear all tasks and results.
|
|
184
|
+
///
|
|
185
|
+
/// All ongoing tasks will be canceled.
|
|
186
|
+
pub fn clear(&mut self) {
|
|
187
|
+
self.tasks.clear();
|
|
188
|
+
self.results.clear();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/// Check if there are remaining space to push new tasks.
|
|
192
|
+
#[inline]
|
|
193
|
+
pub fn has_remaining(&self) -> bool {
|
|
194
|
+
let completed = self.completed_but_unretrieved.load(Ordering::Relaxed);
|
|
195
|
+
// Allow up to `prefetch` completed tasks to be buffered
|
|
196
|
+
self.tasks.len() < self.concurrent + completed.min(self.prefetch)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/// Chunk if there are remaining results to fetch.
|
|
200
|
+
#[inline]
|
|
201
|
+
pub fn has_result(&self) -> bool {
|
|
202
|
+
!self.results.is_empty()
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/// Create a task with given input.
|
|
206
|
+
pub fn create_task(&self, input: I) -> Task<(I, Result<O>)> {
|
|
207
|
+
let completed = self.completed_but_unretrieved.clone();
|
|
208
|
+
|
|
209
|
+
let fut = (self.factory)(input).inspect(move |_| {
|
|
210
|
+
completed.fetch_add(1, Ordering::Relaxed);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
self.executor.execute(fut)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/// Execute the task with given input.
|
|
217
|
+
///
|
|
218
|
+
/// - Execute the task in the current thread if is not concurrent.
|
|
219
|
+
/// - Execute the task in the background if there are available slots.
|
|
220
|
+
/// - Await the first task in the queue if there is no available slots.
|
|
221
|
+
pub async fn execute(&mut self, input: I) -> Result<()> {
|
|
222
|
+
if self.errored {
|
|
223
|
+
return Err(Error::new(
|
|
224
|
+
ErrorKind::Unexpected,
|
|
225
|
+
"concurrent tasks met an unrecoverable error",
|
|
226
|
+
));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Short path for non-concurrent case.
|
|
230
|
+
if !self.is_concurrent() {
|
|
231
|
+
let (_, o) = (self.factory)(input).await;
|
|
232
|
+
return match o {
|
|
233
|
+
Ok(o) => {
|
|
234
|
+
self.results.push_back(o);
|
|
235
|
+
Ok(())
|
|
236
|
+
}
|
|
237
|
+
// We don't need to rebuild the future if it's not concurrent.
|
|
238
|
+
Err(err) => Err(err),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if !self.has_remaining() {
|
|
243
|
+
let (i, o) = self
|
|
244
|
+
.tasks
|
|
245
|
+
.front_mut()
|
|
246
|
+
.expect("tasks must be available")
|
|
247
|
+
.await;
|
|
248
|
+
self.completed_but_unretrieved
|
|
249
|
+
.fetch_sub(1, Ordering::Relaxed);
|
|
250
|
+
match o {
|
|
251
|
+
Ok(o) => {
|
|
252
|
+
let _ = self.tasks.pop_front();
|
|
253
|
+
self.results.push_back(o)
|
|
254
|
+
}
|
|
255
|
+
Err(err) => {
|
|
256
|
+
// Retry this task if the error is temporary
|
|
257
|
+
if err.is_temporary() {
|
|
258
|
+
let task = self.create_task(i);
|
|
259
|
+
self.tasks
|
|
260
|
+
.front_mut()
|
|
261
|
+
.expect("tasks must be available")
|
|
262
|
+
.replace(task)
|
|
263
|
+
} else {
|
|
264
|
+
self.clear();
|
|
265
|
+
self.errored = true;
|
|
266
|
+
}
|
|
267
|
+
return Err(err);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
self.tasks.push_back(self.create_task(input));
|
|
273
|
+
Ok(())
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/// Fetch the successful result from the result queue.
|
|
277
|
+
pub async fn next(&mut self) -> Option<Result<O>> {
|
|
278
|
+
if self.errored {
|
|
279
|
+
return Some(Err(Error::new(
|
|
280
|
+
ErrorKind::Unexpected,
|
|
281
|
+
"concurrent tasks met an unrecoverable error",
|
|
282
|
+
)));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if let Some(result) = self.results.pop_front() {
|
|
286
|
+
return Some(Ok(result));
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if let Some(task) = self.tasks.front_mut() {
|
|
290
|
+
let (i, o) = task.await;
|
|
291
|
+
self.completed_but_unretrieved
|
|
292
|
+
.fetch_sub(1, Ordering::Relaxed);
|
|
293
|
+
return match o {
|
|
294
|
+
Ok(o) => {
|
|
295
|
+
let _ = self.tasks.pop_front();
|
|
296
|
+
Some(Ok(o))
|
|
297
|
+
}
|
|
298
|
+
Err(err) => {
|
|
299
|
+
// Retry this task if the error is temporary
|
|
300
|
+
if err.is_temporary() {
|
|
301
|
+
let task = self.create_task(i);
|
|
302
|
+
self.tasks
|
|
303
|
+
.front_mut()
|
|
304
|
+
.expect("tasks must be available")
|
|
305
|
+
.replace(task)
|
|
306
|
+
} else {
|
|
307
|
+
self.clear();
|
|
308
|
+
self.errored = true;
|
|
309
|
+
}
|
|
310
|
+
Some(Err(err))
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
None
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
#[cfg(test)]
|
|
320
|
+
mod tests {
|
|
321
|
+
use std::time::Duration;
|
|
322
|
+
|
|
323
|
+
use pretty_assertions::assert_eq;
|
|
324
|
+
use rand::Rng;
|
|
325
|
+
use tokio::time::sleep;
|
|
326
|
+
|
|
327
|
+
use super::*;
|
|
328
|
+
|
|
329
|
+
#[tokio::test]
|
|
330
|
+
async fn test_concurrent_tasks() {
|
|
331
|
+
let executor = Executor::new();
|
|
332
|
+
|
|
333
|
+
let mut tasks = ConcurrentTasks::new(executor, 16, 8, |(i, dur)| {
|
|
334
|
+
Box::pin(async move {
|
|
335
|
+
sleep(dur).await;
|
|
336
|
+
|
|
337
|
+
// 5% rate to fail.
|
|
338
|
+
if rand::thread_rng().gen_range(0..100) > 90 {
|
|
339
|
+
return (
|
|
340
|
+
(i, dur),
|
|
341
|
+
Err(Error::new(ErrorKind::Unexpected, "I'm lucky").set_temporary()),
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
((i, dur), Ok(i))
|
|
345
|
+
})
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
let mut ans = vec![];
|
|
349
|
+
|
|
350
|
+
for i in 0..10240 {
|
|
351
|
+
// Sleep up to 10ms
|
|
352
|
+
let dur = Duration::from_millis(rand::thread_rng().gen_range(0..10));
|
|
353
|
+
loop {
|
|
354
|
+
let res = tasks.execute((i, dur)).await;
|
|
355
|
+
if res.is_ok() {
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
loop {
|
|
362
|
+
match tasks.next().await.transpose() {
|
|
363
|
+
Ok(Some(i)) => ans.push(i),
|
|
364
|
+
Ok(None) => break,
|
|
365
|
+
Err(_) => continue,
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
assert_eq!(ans, (0..10240).collect::<Vec<_>>())
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
#[tokio::test]
|
|
373
|
+
async fn test_prefetch_backpressure() {
|
|
374
|
+
let executor = Executor::new();
|
|
375
|
+
let concurrent = 4;
|
|
376
|
+
let prefetch = 2;
|
|
377
|
+
|
|
378
|
+
// Create a slower task to ensure they don't complete immediately
|
|
379
|
+
let mut tasks = ConcurrentTasks::new(executor, concurrent, prefetch, |i: usize| {
|
|
380
|
+
Box::pin(async move {
|
|
381
|
+
sleep(Duration::from_millis(100)).await;
|
|
382
|
+
(i, Ok(i))
|
|
383
|
+
})
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// Initially, we should have space for concurrent tasks
|
|
387
|
+
assert!(tasks.has_remaining(), "Should have space initially");
|
|
388
|
+
|
|
389
|
+
// Submit concurrent tasks
|
|
390
|
+
for i in 0..concurrent {
|
|
391
|
+
assert!(tasks.has_remaining(), "Should have space for task {i}");
|
|
392
|
+
tasks.execute(i).await.unwrap();
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// Now we shouldn't have any more space (since no tasks have completed yet)
|
|
396
|
+
assert!(
|
|
397
|
+
!tasks.has_remaining(),
|
|
398
|
+
"Should not have space after submitting concurrent tasks"
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
// Wait for some tasks to complete
|
|
402
|
+
sleep(Duration::from_millis(150)).await;
|
|
403
|
+
|
|
404
|
+
// Now we should have space up to prefetch limit
|
|
405
|
+
for i in concurrent..concurrent + prefetch {
|
|
406
|
+
assert!(
|
|
407
|
+
tasks.has_remaining(),
|
|
408
|
+
"Should have space for prefetch task {i}"
|
|
409
|
+
);
|
|
410
|
+
tasks.execute(i).await.unwrap();
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Now has_remaining should return false
|
|
414
|
+
assert!(
|
|
415
|
+
!tasks.has_remaining(),
|
|
416
|
+
"Should not have remaining space after filling up prefetch buffer"
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
// Retrieve one result
|
|
420
|
+
let result = tasks.next().await;
|
|
421
|
+
assert!(result.is_some());
|
|
422
|
+
|
|
423
|
+
// Now there should be space for one more task
|
|
424
|
+
assert!(
|
|
425
|
+
tasks.has_remaining(),
|
|
426
|
+
"Should have remaining space after retrieving one result"
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
#[tokio::test]
|
|
431
|
+
async fn test_prefetch_zero() {
|
|
432
|
+
let executor = Executor::new();
|
|
433
|
+
let concurrent = 4;
|
|
434
|
+
let prefetch = 0; // No prefetching allowed
|
|
435
|
+
|
|
436
|
+
let mut tasks = ConcurrentTasks::new(executor, concurrent, prefetch, |i: usize| {
|
|
437
|
+
Box::pin(async move {
|
|
438
|
+
sleep(Duration::from_millis(10)).await;
|
|
439
|
+
(i, Ok(i))
|
|
440
|
+
})
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
// With prefetch=0, we can only submit up to concurrent tasks
|
|
444
|
+
for i in 0..concurrent {
|
|
445
|
+
tasks.execute(i).await.unwrap();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Should not have space for more
|
|
449
|
+
assert!(
|
|
450
|
+
!tasks.has_remaining(),
|
|
451
|
+
"Should not have remaining space with prefetch=0"
|
|
452
|
+
);
|
|
453
|
+
|
|
454
|
+
// Retrieve one result
|
|
455
|
+
let result = tasks.next().await;
|
|
456
|
+
assert!(result.is_some());
|
|
457
|
+
|
|
458
|
+
// Now there should be space for exactly one more task
|
|
459
|
+
assert!(
|
|
460
|
+
tasks.has_remaining(),
|
|
461
|
+
"Should have remaining space after retrieving one result"
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
// Execute one more
|
|
465
|
+
tasks.execute(concurrent).await.unwrap();
|
|
466
|
+
|
|
467
|
+
// Should be full again
|
|
468
|
+
assert!(!tasks.has_remaining(), "Should be full again");
|
|
469
|
+
}
|
|
470
|
+
}
|