opendal 0.1.9 → 0.1.11
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 +4 -4
- data/Cargo.lock +89 -56
- data/Cargo.toml +1 -1
- data/DEPENDENCIES.rust.tsv +55 -41
- data/LICENSE +201 -0
- data/LICENSE-MPL-2.0.txt +373 -0
- data/NOTICE +5 -0
- data/core/CHANGELOG.md +175 -0
- data/core/Cargo.lock +225 -298
- data/core/Cargo.toml +100 -94
- data/core/DEPENDENCIES.rust.tsv +44 -73
- data/core/benches/metadata/README.md +21 -0
- data/core/benches/metadata/main.rs +541 -0
- data/core/benches/vs_fs/Cargo.toml +1 -1
- data/core/benches/vs_s3/Cargo.toml +1 -1
- data/core/core/Cargo.toml +7 -2
- data/core/core/src/blocking/delete.rs +5 -1
- data/core/core/src/blocking/operator.rs +12 -0
- data/core/core/src/blocking/read/std_reader.rs +25 -0
- data/core/core/src/docs/concepts.rs +70 -94
- data/core/core/src/docs/internals/accessor.rs +62 -293
- data/core/core/src/docs/internals/layer.rs +43 -59
- data/core/core/src/docs/internals/mod.rs +21 -23
- data/core/core/src/docs/mod.rs +10 -6
- data/core/core/src/docs/performance/concurrent_write.md +92 -55
- data/core/core/src/docs/performance/http_optimization.md +120 -104
- data/core/core/src/docs/performance/mod.rs +8 -6
- data/core/core/src/docs/rfcs/5485_conditional_reader.md +4 -0
- data/core/core/src/docs/rfcs/7182_restore_api.md +139 -557
- data/core/core/src/docs/rfcs/7945_limited_read.md +210 -0
- data/core/core/src/docs/rfcs/7948_s3_provider_presets.md +254 -0
- data/core/core/src/docs/rfcs/8109_writer_copy_from.md +330 -0
- data/core/core/src/docs/rfcs/8145_conflict_error_kind.md +210 -0
- data/core/core/src/docs/rfcs/8147_write_if_not_changed.md +233 -0
- data/core/core/src/docs/rfcs/8188_compose_api.md +292 -0
- data/core/core/src/docs/rfcs/8194_compact_metadata_and_operation_args.md +444 -0
- data/core/core/src/docs/rfcs/README.md +14 -3
- data/core/core/src/docs/rfcs/mod.rs +46 -22
- data/core/core/src/docs/specs/README.md +34 -0
- data/core/core/src/docs/specs/conditional-operations.md +156 -0
- data/core/core/src/docs/specs/metadata.md +63 -0
- data/core/core/src/docs/specs/mod.rs +26 -0
- data/core/core/src/docs/upgrade.md +114 -1
- data/core/core/src/layers/capability_override.rs +15 -2
- data/core/core/src/layers/complete.rs +347 -43
- data/core/core/src/layers/correctness_check.rs +718 -51
- data/core/core/src/layers/error_context.rs +76 -2
- data/core/core/src/layers/simulate.rs +91 -28
- data/core/core/src/lib.rs +1 -0
- data/core/core/src/raw/accessor.rs +91 -15
- data/core/core/src/raw/enum_utils.rs +7 -0
- data/core/core/src/raw/http_util/header.rs +22 -17
- data/core/core/src/raw/oio/compose/api.rs +92 -0
- data/core/core/src/raw/oio/compose/mod.rs +19 -0
- data/core/core/src/raw/oio/copy/api.rs +3 -3
- data/core/core/src/raw/oio/copy/block_copy.rs +32 -4
- data/core/core/src/raw/oio/copy/multipart_copy.rs +36 -7
- data/core/core/src/raw/oio/entry.rs +48 -22
- data/core/core/src/raw/oio/list/flat_list.rs +1 -1
- data/core/core/src/raw/oio/list/hierarchy_list.rs +3 -2
- data/core/core/src/raw/oio/mod.rs +3 -0
- data/core/core/src/raw/oio/read/position_read.rs +1 -1
- data/core/core/src/raw/oio/write/api.rs +40 -0
- data/core/core/src/raw/oio/write/append_write.rs +4 -4
- data/core/core/src/raw/oio/write/block_write.rs +2 -2
- data/core/core/src/raw/oio/write/multipart_write.rs +181 -48
- data/core/core/src/raw/oio/write/position_write.rs +1 -1
- data/core/core/src/raw/operation.rs +6 -0
- data/core/core/src/raw/ops.rs +1191 -456
- data/core/core/src/raw/rps.rs +11 -0
- data/core/core/src/raw/time.rs +14 -3
- data/core/core/src/services/memory/backend.rs +5 -10
- data/core/core/src/services/memory/lister.rs +4 -4
- data/core/core/src/services/memory/writer.rs +7 -6
- data/core/core/src/types/buffer.rs +102 -12
- data/core/core/src/types/bytes_range.rs +20 -1
- data/core/core/src/types/capability.rs +65 -0
- data/core/core/src/types/compact.rs +329 -0
- data/core/core/src/types/compose/composer.rs +183 -0
- data/core/core/src/types/compose/input.rs +57 -0
- data/core/core/src/types/compose/mod.rs +23 -0
- data/core/core/src/types/context/read.rs +16 -11
- data/core/core/src/types/context/write.rs +150 -2
- data/core/core/src/types/copy.rs +5 -3
- data/core/core/src/types/delete/deleter.rs +20 -12
- data/core/core/src/types/delete/input.rs +22 -64
- data/core/core/src/types/delete/mod.rs +0 -1
- data/core/core/src/types/entry.rs +8 -14
- data/core/core/src/types/error.rs +28 -11
- data/core/core/src/types/metadata.rs +709 -322
- data/core/core/src/types/mod.rs +9 -1
- data/core/core/src/types/operator/operator.rs +278 -29
- data/core/core/src/types/operator/operator_futures.rs +466 -105
- data/core/core/src/types/options.rs +631 -158
- data/core/core/src/types/read/futures_async_reader.rs +663 -50
- data/core/core/src/types/read/reader.rs +23 -5
- data/core/core/src/types/write/futures_async_writer.rs +27 -0
- data/core/core/src/types/write/writer.rs +47 -5
- data/core/http-transports/reqwest/Cargo.toml +1 -1
- data/core/layers/async-backtrace/Cargo.toml +2 -2
- data/core/layers/async-backtrace/src/lib.rs +21 -2
- data/core/layers/await-tree/Cargo.toml +2 -2
- data/core/layers/await-tree/src/lib.rs +25 -2
- data/core/layers/capability-check/Cargo.toml +2 -2
- data/core/layers/capability-check/src/lib.rs +98 -10
- data/core/layers/chaos/Cargo.toml +2 -2
- data/core/layers/chaos/src/lib.rs +18 -3
- data/core/layers/concurrent-limit/Cargo.toml +3 -3
- data/core/layers/concurrent-limit/src/lib.rs +53 -13
- data/core/layers/dtrace/Cargo.toml +2 -2
- data/core/layers/dtrace/src/lib.rs +29 -2
- data/core/layers/fastmetrics/Cargo.toml +3 -3
- data/core/layers/fastrace/Cargo.toml +2 -2
- data/core/layers/fastrace/src/lib.rs +28 -2
- data/core/layers/foyer/Cargo.toml +2 -2
- data/core/layers/foyer/src/full.rs +16 -19
- data/core/layers/foyer/src/lib.rs +67 -14
- data/core/layers/hotpath/Cargo.toml +2 -2
- data/core/layers/hotpath/src/lib.rs +20 -2
- data/core/layers/immutable-index/Cargo.toml +2 -2
- data/core/layers/immutable-index/src/lib.rs +48 -24
- data/core/layers/logging/Cargo.toml +2 -2
- data/core/layers/logging/src/lib.rs +46 -2
- data/core/layers/metrics/Cargo.toml +3 -3
- data/core/layers/mime-guess/Cargo.toml +2 -2
- data/core/layers/mime-guess/src/lib.rs +31 -4
- data/core/layers/observe-metrics-common/Cargo.toml +2 -2
- data/core/layers/observe-metrics-common/src/lib.rs +55 -2
- data/core/layers/otelmetrics/Cargo.toml +3 -3
- data/core/layers/oteltrace/Cargo.toml +2 -2
- data/core/layers/oteltrace/src/lib.rs +27 -2
- data/core/layers/prometheus/Cargo.toml +3 -3
- data/core/layers/prometheus-client/Cargo.toml +3 -3
- data/core/layers/retry/Cargo.toml +4 -4
- data/core/layers/retry/src/lib.rs +76 -19
- data/core/layers/route/Cargo.toml +3 -3
- data/core/layers/route/src/lib.rs +34 -7
- data/core/layers/tail-cut/Cargo.toml +2 -2
- data/core/layers/tail-cut/src/lib.rs +28 -2
- data/core/layers/throttle/Cargo.toml +2 -2
- data/core/layers/throttle/src/lib.rs +19 -2
- data/core/layers/timeout/Cargo.toml +3 -3
- data/core/layers/timeout/src/lib.rs +38 -13
- data/core/layers/tracing/Cargo.toml +2 -2
- data/core/layers/tracing/src/lib.rs +24 -3
- data/core/services/aliyun-drive/Cargo.toml +2 -2
- data/core/services/aliyun-drive/src/backend.rs +34 -24
- data/core/services/aliyun-drive/src/core.rs +143 -54
- data/core/services/aliyun-drive/src/lister.rs +19 -18
- data/core/services/aliyun-drive/src/reader.rs +4 -1
- data/core/services/aliyun-drive/src/writer.rs +3 -3
- data/core/services/alluxio/Cargo.toml +1 -1
- data/core/services/alluxio/src/backend.rs +1 -1
- data/core/services/alluxio/src/core.rs +113 -94
- data/core/services/alluxio/src/reader.rs +7 -3
- data/core/services/alluxio/src/writer.rs +2 -2
- data/core/services/azblob/Cargo.toml +2 -2
- data/core/services/azblob/src/backend.rs +17 -9
- data/core/services/azblob/src/copier.rs +41 -15
- data/core/services/azblob/src/core.rs +372 -135
- data/core/services/azblob/src/deleter.rs +41 -18
- data/core/services/azblob/src/lister.rs +16 -10
- data/core/services/azblob/src/reader.rs +4 -1
- data/core/services/azblob/src/writer.rs +48 -15
- data/core/services/azdls/Cargo.toml +3 -3
- data/core/services/azdls/src/backend.rs +45 -15
- data/core/services/azdls/src/config.rs +4 -1
- data/core/services/azdls/src/core.rs +276 -87
- data/core/services/azdls/src/deleter.rs +13 -4
- data/core/services/azdls/src/lister.rs +18 -12
- data/core/services/azdls/src/reader.rs +6 -2
- data/core/services/azdls/src/writer.rs +44 -23
- data/core/services/azfile/Cargo.toml +2 -2
- data/core/services/azfile/src/backend.rs +24 -8
- data/core/services/azfile/src/core.rs +195 -77
- data/core/services/azfile/src/deleter.rs +8 -1
- data/core/services/azfile/src/lister.rs +20 -14
- data/core/services/azfile/src/reader.rs +5 -2
- data/core/services/azfile/src/writer.rs +27 -15
- data/core/services/azure-common/Cargo.toml +1 -1
- data/core/services/b2/Cargo.toml +2 -2
- data/core/services/b2/src/backend.rs +30 -11
- data/core/services/b2/src/core.rs +134 -120
- data/core/services/b2/src/deleter.rs +1 -1
- data/core/services/b2/src/lister.rs +5 -2
- data/core/services/b2/src/reader.rs +5 -2
- data/core/services/b2/src/writer.rs +29 -12
- data/core/services/cacache/Cargo.toml +1 -1
- data/core/services/cacache/src/backend.rs +4 -5
- data/core/services/cacache/src/reader.rs +4 -1
- data/core/services/cacache/src/writer.rs +6 -2
- data/core/services/cloudflare-kv/Cargo.toml +1 -1
- data/core/services/cloudflare-kv/src/backend.rs +26 -15
- data/core/services/cloudflare-kv/src/config.rs +13 -2
- data/core/services/cloudflare-kv/src/core.rs +62 -56
- data/core/services/cloudflare-kv/src/deleter.rs +12 -3
- data/core/services/cloudflare-kv/src/lister.rs +66 -17
- data/core/services/cloudflare-kv/src/reader.rs +14 -9
- data/core/services/cloudflare-kv/src/writer.rs +10 -7
- data/core/services/compfs/Cargo.toml +1 -1
- data/core/services/compfs/src/backend.rs +11 -7
- data/core/services/compfs/src/lister.rs +7 -7
- data/core/services/compfs/src/writer.rs +1 -1
- data/core/services/cos/Cargo.toml +1 -1
- data/core/services/cos/src/backend.rs +129 -16
- data/core/services/cos/src/core.rs +198 -80
- data/core/services/cos/src/deleter.rs +4 -1
- data/core/services/cos/src/lister.rs +42 -27
- data/core/services/cos/src/reader.rs +6 -2
- data/core/services/cos/src/writer.rs +45 -21
- data/core/services/d1/Cargo.toml +1 -1
- data/core/services/d1/src/backend.rs +6 -5
- data/core/services/d1/src/core.rs +79 -63
- data/core/services/d1/src/reader.rs +4 -1
- data/core/services/d1/src/writer.rs +6 -2
- data/core/services/dashmap/Cargo.toml +1 -1
- data/core/services/dashmap/src/backend.rs +2 -2
- data/core/services/dashmap/src/reader.rs +4 -1
- data/core/services/dashmap/src/writer.rs +11 -8
- data/core/services/dbfs/Cargo.toml +1 -1
- data/core/services/dbfs/src/backend.rs +21 -15
- data/core/services/dbfs/src/core.rs +65 -60
- data/core/services/dbfs/src/deleter.rs +4 -1
- data/core/services/dbfs/src/lister.rs +10 -10
- data/core/services/dbfs/src/writer.rs +6 -3
- data/core/services/dropbox/Cargo.toml +2 -2
- data/core/services/dropbox/src/backend.rs +30 -23
- data/core/services/dropbox/src/core.rs +65 -63
- data/core/services/dropbox/src/deleter.rs +1 -1
- data/core/services/dropbox/src/lister.rs +17 -8
- data/core/services/dropbox/src/reader.rs +4 -1
- data/core/services/dropbox/src/writer.rs +13 -10
- data/core/services/etcd/Cargo.toml +1 -1
- data/core/services/etcd/src/backend.rs +8 -5
- data/core/services/etcd/src/core.rs +5 -11
- data/core/services/etcd/src/lister.rs +6 -1
- data/core/services/etcd/src/reader.rs +4 -1
- data/core/services/etcd/src/writer.rs +6 -3
- data/core/services/foundationdb/Cargo.toml +1 -1
- data/core/services/foundationdb/src/backend.rs +6 -5
- data/core/services/foundationdb/src/reader.rs +4 -1
- data/core/services/foundationdb/src/writer.rs +6 -2
- data/core/services/foyer/Cargo.toml +3 -3
- data/core/services/foyer/src/backend.rs +6 -5
- data/core/services/foyer/src/reader.rs +4 -1
- data/core/services/foyer/src/writer.rs +6 -2
- data/core/services/fs/Cargo.toml +1 -1
- data/core/services/fs/src/backend.rs +4 -3
- data/core/services/fs/src/core.rs +44 -26
- data/core/services/fs/src/lister.rs +9 -6
- data/core/services/fs/src/writer.rs +20 -13
- data/core/services/ftp/Cargo.toml +4 -6
- data/core/services/ftp/src/backend.rs +9 -5
- data/core/services/ftp/src/core.rs +9 -7
- data/core/services/ftp/src/lister.rs +7 -8
- data/core/services/ftp/src/reader.rs +3 -3
- data/core/services/ftp/src/writer.rs +3 -3
- data/core/services/gcs/Cargo.toml +4 -2
- data/core/services/gcs/src/backend.rs +53 -7
- data/core/services/gcs/src/composer.rs +705 -0
- data/core/services/gcs/src/copier.rs +14 -4
- data/core/services/gcs/src/core.rs +828 -124
- data/core/services/gcs/src/deleter.rs +33 -18
- data/core/services/gcs/src/lib.rs +1 -0
- data/core/services/gcs/src/lister.rs +21 -12
- data/core/services/gcs/src/reader.rs +12 -5
- data/core/services/gcs/src/writer.rs +632 -10
- data/core/services/gcs-grpc/Cargo.toml +58 -0
- data/core/services/gcs-grpc/README.md +19 -0
- data/core/services/gcs-grpc/proto/README.md +23 -0
- data/core/services/gcs-grpc/proto/google/storage/v2/storage.proto +171 -0
- data/core/services/gcs-grpc/proto/upstream-descriptor.bin +0 -0
- data/core/services/gcs-grpc/src/backend.rs +449 -0
- data/core/services/gcs-grpc/src/config.rs +116 -0
- data/core/services/gcs-grpc/src/copier.rs +98 -0
- data/core/services/gcs-grpc/src/core.rs +298 -0
- data/core/services/gcs-grpc/src/deleter.rs +65 -0
- data/core/services/gcs-grpc/src/docs.md +19 -0
- data/core/services/gcs-grpc/src/generated/google.storage.v2.rs +541 -0
- data/core/services/gcs-grpc/src/generated/mod.rs +24 -0
- data/core/services/gcs-grpc/src/lib.rs +43 -0
- data/core/services/gcs-grpc/src/lister.rs +125 -0
- data/core/services/gcs-grpc/src/reader.rs +140 -0
- data/core/services/gcs-grpc/src/writer.rs +780 -0
- data/core/services/gdrive/Cargo.toml +2 -2
- data/core/services/gdrive/src/backend.rs +123 -69
- data/core/services/gdrive/src/core.rs +87 -69
- data/core/services/gdrive/src/deleter.rs +8 -2
- data/core/services/gdrive/src/lister.rs +38 -26
- data/core/services/gdrive/src/path_index.rs +2 -2
- data/core/services/gdrive/src/reader.rs +9 -3
- data/core/services/gdrive/src/writer.rs +13 -7
- data/core/services/ghac/Cargo.toml +2 -2
- data/core/services/ghac/src/backend.rs +5 -2
- data/core/services/ghac/src/core.rs +59 -37
- data/core/services/ghac/src/reader.rs +5 -2
- data/core/services/ghac/src/writer.rs +16 -6
- data/core/services/github/Cargo.toml +1 -1
- data/core/services/github/src/backend.rs +16 -8
- data/core/services/github/src/core.rs +88 -76
- data/core/services/github/src/lister.rs +17 -15
- data/core/services/github/src/reader.rs +5 -2
- data/core/services/github/src/writer.rs +12 -6
- data/core/services/goosefs/Cargo.toml +2 -2
- data/core/services/goosefs/src/backend.rs +2 -2
- data/core/services/goosefs/src/core.rs +291 -208
- data/core/services/goosefs/src/docs.md +3 -0
- data/core/services/goosefs/src/lister.rs +2 -3
- data/core/services/goosefs/src/reader.rs +7 -3
- data/core/services/goosefs/src/writer.rs +21 -10
- data/core/services/goosefs/tests/safe_conditional_put.rs +37 -0
- data/core/services/gridfs/Cargo.toml +2 -2
- data/core/services/gridfs/src/backend.rs +12 -8
- data/core/services/gridfs/src/core.rs +1 -1
- data/core/services/gridfs/src/reader.rs +4 -1
- data/core/services/gridfs/src/writer.rs +6 -2
- data/core/services/hdfs/Cargo.toml +1 -1
- data/core/services/hdfs/src/backend.rs +1 -1
- data/core/services/hdfs/src/core.rs +7 -4
- data/core/services/hdfs/src/lister.rs +7 -9
- data/core/services/hdfs/src/writer.rs +5 -1
- data/core/services/hdfs-native/Cargo.toml +1 -1
- data/core/services/hdfs-native/src/backend.rs +1 -1
- data/core/services/hdfs-native/src/core.rs +44 -50
- data/core/services/hdfs-native/src/lister.rs +8 -10
- data/core/services/hdfs-native/src/writer.rs +5 -1
- data/core/services/hf/Cargo.toml +4 -3
- data/core/services/hf/src/backend.rs +4 -3
- data/core/services/hf/src/core.rs +907 -153
- data/core/services/hf/src/lister.rs +16 -6
- data/core/services/hf/src/reader.rs +377 -57
- data/core/services/hf/src/writer.rs +6 -2
- data/core/services/http/Cargo.toml +3 -3
- data/core/services/http/src/backend.rs +8 -6
- data/core/services/http/src/core.rs +57 -35
- data/core/services/http/src/reader.rs +5 -2
- data/core/services/ipfs/Cargo.toml +1 -1
- data/core/services/ipfs/src/backend.rs +20 -9
- data/core/services/ipfs/src/core.rs +43 -34
- data/core/services/ipfs/src/reader.rs +5 -2
- data/core/services/ipmfs/Cargo.toml +1 -1
- data/core/services/ipmfs/src/backend.rs +17 -8
- data/core/services/ipmfs/src/core.rs +66 -60
- data/core/services/ipmfs/src/deleter.rs +5 -2
- data/core/services/ipmfs/src/lister.rs +15 -12
- data/core/services/ipmfs/src/reader.rs +5 -2
- data/core/services/ipmfs/src/writer.rs +6 -3
- data/core/services/koofr/Cargo.toml +2 -2
- data/core/services/koofr/src/backend.rs +46 -17
- data/core/services/koofr/src/core.rs +64 -48
- data/core/services/koofr/src/deleter.rs +4 -1
- data/core/services/koofr/src/lister.rs +11 -10
- data/core/services/koofr/src/reader.rs +5 -2
- data/core/services/koofr/src/writer.rs +13 -7
- data/core/services/lakefs/Cargo.toml +1 -1
- data/core/services/lakefs/src/backend.rs +25 -8
- data/core/services/lakefs/src/core.rs +79 -73
- data/core/services/lakefs/src/deleter.rs +4 -1
- data/core/services/lakefs/src/lister.rs +17 -14
- data/core/services/lakefs/src/reader.rs +5 -2
- data/core/services/lakefs/src/writer.rs +11 -10
- data/core/services/memcached/Cargo.toml +1 -1
- data/core/services/memcached/src/backend.rs +57 -7
- data/core/services/memcached/src/config.rs +13 -2
- data/core/services/memcached/src/core.rs +11 -1
- data/core/services/memcached/src/reader.rs +4 -1
- data/core/services/memcached/src/writer.rs +6 -2
- data/core/services/mini_moka/Cargo.toml +1 -1
- data/core/services/mini_moka/src/backend.rs +8 -8
- data/core/services/mini_moka/src/reader.rs +4 -1
- data/core/services/mini_moka/src/writer.rs +11 -7
- data/core/services/moka/Cargo.toml +1 -1
- data/core/services/moka/src/backend.rs +7 -7
- data/core/services/moka/src/reader.rs +4 -1
- data/core/services/moka/src/writer.rs +10 -6
- data/core/services/mongodb/Cargo.toml +2 -2
- data/core/services/mongodb/src/backend.rs +7 -6
- data/core/services/mongodb/src/core.rs +1 -1
- data/core/services/mongodb/src/reader.rs +4 -1
- data/core/services/mongodb/src/writer.rs +6 -2
- data/core/services/monoiofs/Cargo.toml +2 -2
- data/core/services/monoiofs/src/backend.rs +16 -10
- data/core/services/monoiofs/src/core.rs +8 -9
- data/core/services/monoiofs/src/reader.rs +8 -10
- data/core/services/monoiofs/src/writer.rs +19 -24
- data/core/services/mysql/Cargo.toml +2 -2
- data/core/services/mysql/src/backend.rs +7 -6
- data/core/services/mysql/src/core.rs +1 -1
- data/core/services/mysql/src/lister.rs +7 -3
- data/core/services/mysql/src/reader.rs +4 -1
- data/core/services/mysql/src/writer.rs +6 -2
- data/core/services/obs/Cargo.toml +1 -1
- data/core/services/obs/src/backend.rs +29 -11
- data/core/services/obs/src/core.rs +81 -82
- data/core/services/obs/src/deleter.rs +4 -1
- data/core/services/obs/src/lister.rs +12 -5
- data/core/services/obs/src/reader.rs +5 -2
- data/core/services/obs/src/writer.rs +40 -19
- data/core/services/onedrive/Cargo.toml +2 -2
- data/core/services/onedrive/src/backend.rs +30 -21
- data/core/services/onedrive/src/config.rs +2 -2
- data/core/services/onedrive/src/core.rs +191 -90
- data/core/services/onedrive/src/deleter.rs +5 -2
- data/core/services/onedrive/src/graph_model.rs +10 -51
- data/core/services/onedrive/src/lister.rs +60 -24
- data/core/services/onedrive/src/reader.rs +17 -2
- data/core/services/onedrive/src/writer.rs +26 -15
- data/core/services/opfs/Cargo.toml +1 -1
- data/core/services/opfs/src/backend.rs +6 -13
- data/core/services/opfs/src/core.rs +33 -37
- data/core/services/opfs/src/lister.rs +4 -4
- data/core/services/opfs/src/writer.rs +1 -3
- data/core/services/oss/Cargo.toml +1 -1
- data/core/services/oss/src/backend.rs +40 -8
- data/core/services/oss/src/core.rs +192 -92
- data/core/services/oss/src/deleter.rs +16 -6
- data/core/services/oss/src/lister.rs +43 -27
- data/core/services/oss/src/reader.rs +6 -2
- data/core/services/oss/src/writer.rs +40 -22
- data/core/services/pcloud/Cargo.toml +1 -1
- data/core/services/pcloud/src/backend.rs +40 -6
- data/core/services/pcloud/src/core.rs +80 -66
- data/core/services/pcloud/src/deleter.rs +8 -1
- data/core/services/pcloud/src/lister.rs +4 -1
- data/core/services/pcloud/src/reader.rs +5 -2
- data/core/services/pcloud/src/writer.rs +6 -3
- data/core/services/persy/Cargo.toml +1 -1
- data/core/services/persy/src/backend.rs +6 -5
- data/core/services/persy/src/core.rs +60 -15
- data/core/services/persy/src/reader.rs +4 -1
- data/core/services/persy/src/writer.rs +6 -2
- data/core/services/postgresql/Cargo.toml +2 -2
- data/core/services/postgresql/src/backend.rs +7 -6
- data/core/services/postgresql/src/core.rs +1 -1
- data/core/services/postgresql/src/reader.rs +4 -1
- data/core/services/postgresql/src/writer.rs +6 -2
- data/core/services/redb/Cargo.toml +1 -1
- data/core/services/redb/src/backend.rs +6 -5
- data/core/services/redb/src/reader.rs +4 -1
- data/core/services/redb/src/writer.rs +6 -2
- data/core/services/redis/Cargo.toml +1 -1
- data/core/services/redis/src/backend.rs +18 -8
- data/core/services/redis/src/config.rs +13 -2
- data/core/services/redis/src/reader.rs +8 -4
- data/core/services/redis/src/writer.rs +6 -2
- data/core/services/rocksdb/Cargo.toml +1 -1
- data/core/services/rocksdb/src/backend.rs +6 -5
- data/core/services/rocksdb/src/lister.rs +6 -5
- data/core/services/rocksdb/src/reader.rs +4 -1
- data/core/services/rocksdb/src/writer.rs +6 -2
- data/core/services/s3/Cargo.toml +5 -4
- data/core/services/s3/src/backend.rs +995 -39
- data/core/services/s3/src/compatible_services.md +57 -0
- data/core/services/s3/src/config.rs +16 -0
- data/core/services/s3/src/copier.rs +190 -55
- data/core/services/s3/src/core.rs +299 -190
- data/core/services/s3/src/deleter.rs +26 -7
- data/core/services/s3/src/docs.md +57 -0
- data/core/services/s3/src/lister.rs +55 -36
- data/core/services/s3/src/reader.rs +22 -2
- data/core/services/s3/src/writer.rs +154 -32
- data/core/services/seafile/Cargo.toml +2 -2
- data/core/services/seafile/src/backend.rs +3 -3
- data/core/services/seafile/src/core.rs +105 -79
- data/core/services/seafile/src/lister.rs +11 -8
- data/core/services/seafile/src/reader.rs +5 -2
- data/core/services/seafile/src/writer.rs +6 -3
- data/core/services/sftp/Cargo.toml +1 -1
- data/core/services/sftp/src/backend.rs +19 -4
- data/core/services/sftp/src/core.rs +51 -46
- data/core/services/sftp/src/lister.rs +4 -4
- data/core/services/sftp/src/writer.rs +1 -1
- data/core/services/sled/Cargo.toml +1 -1
- data/core/services/sled/src/backend.rs +6 -5
- data/core/services/sled/src/core.rs +28 -6
- data/core/services/sled/src/lister.rs +6 -5
- data/core/services/sled/src/reader.rs +4 -1
- data/core/services/sled/src/writer.rs +6 -2
- data/core/services/sqlite/Cargo.toml +2 -2
- data/core/services/sqlite/src/backend.rs +12 -7
- data/core/services/sqlite/src/core.rs +3 -3
- data/core/services/sqlite/src/reader.rs +4 -1
- data/core/services/sqlite/src/writer.rs +7 -3
- data/core/services/surrealdb/Cargo.toml +2 -2
- data/core/services/surrealdb/src/backend.rs +7 -6
- data/core/services/surrealdb/src/core.rs +1 -1
- data/core/services/surrealdb/src/reader.rs +4 -1
- data/core/services/surrealdb/src/writer.rs +6 -2
- data/core/services/swift/Cargo.toml +1 -1
- data/core/services/swift/src/backend.rs +38 -8
- data/core/services/swift/src/core.rs +63 -67
- data/core/services/swift/src/deleter.rs +8 -2
- data/core/services/swift/src/lister.rs +11 -8
- data/core/services/swift/src/reader.rs +5 -2
- data/core/services/swift/src/writer.rs +17 -8
- data/core/services/tikv/Cargo.toml +2 -2
- data/core/services/tikv/src/backend.rs +7 -6
- data/core/services/tikv/src/core.rs +31 -14
- data/core/services/tikv/src/reader.rs +4 -1
- data/core/services/tikv/src/writer.rs +6 -2
- data/core/services/tos/Cargo.toml +2 -2
- data/core/services/tos/src/backend.rs +45 -21
- data/core/services/tos/src/copier.rs +44 -17
- data/core/services/tos/src/core.rs +147 -117
- data/core/services/tos/src/deleter.rs +9 -3
- data/core/services/tos/src/docs.md +1 -1
- data/core/services/tos/src/lister.rs +43 -28
- data/core/services/tos/src/reader.rs +5 -2
- data/core/services/tos/src/writer.rs +37 -16
- data/core/services/upyun/Cargo.toml +1 -1
- data/core/services/upyun/src/backend.rs +30 -7
- data/core/services/upyun/src/core.rs +122 -87
- data/core/services/upyun/src/deleter.rs +4 -1
- data/core/services/upyun/src/lister.rs +10 -10
- data/core/services/upyun/src/reader.rs +5 -2
- data/core/services/upyun/src/writer.rs +19 -7
- data/core/services/vercel-artifacts/Cargo.toml +1 -1
- data/core/services/vercel-artifacts/src/backend.rs +6 -3
- data/core/services/vercel-artifacts/src/core.rs +32 -27
- data/core/services/vercel-artifacts/src/reader.rs +5 -2
- data/core/services/vercel-artifacts/src/writer.rs +6 -3
- data/core/services/vercel-blob/Cargo.toml +1 -1
- data/core/services/vercel-blob/src/backend.rs +23 -6
- data/core/services/vercel-blob/src/core.rs +92 -81
- data/core/services/vercel-blob/src/lister.rs +12 -3
- data/core/services/vercel-blob/src/reader.rs +5 -2
- data/core/services/vercel-blob/src/writer.rs +19 -7
- data/core/services/webdav/Cargo.toml +2 -2
- data/core/services/webdav/src/backend.rs +25 -5
- data/core/services/webdav/src/core.rs +116 -59
- data/core/services/webdav/src/deleter.rs +4 -1
- data/core/services/webdav/src/lister.rs +4 -1
- data/core/services/webdav/src/reader.rs +6 -2
- data/core/services/webdav/src/writer.rs +17 -7
- data/core/services/webhdfs/Cargo.toml +2 -2
- data/core/services/webhdfs/src/backend.rs +24 -11
- data/core/services/webhdfs/src/core.rs +99 -98
- data/core/services/webhdfs/src/deleter.rs +5 -2
- data/core/services/webhdfs/src/lister.rs +21 -9
- data/core/services/webhdfs/src/reader.rs +5 -2
- data/core/services/webhdfs/src/writer.rs +49 -14
- data/core/services/yandex-disk/Cargo.toml +1 -1
- data/core/services/yandex-disk/src/backend.rs +28 -6
- data/core/services/yandex-disk/src/core.rs +97 -79
- data/core/services/yandex-disk/src/deleter.rs +4 -1
- data/core/services/yandex-disk/src/lister.rs +25 -9
- data/core/services/yandex-disk/src/reader.rs +5 -2
- data/core/services/yandex-disk/src/writer.rs +6 -3
- data/core/src/lib.rs +5 -0
- data/core/testkit/Cargo.toml +4 -4
- data/core/testkit/src/utils.rs +53 -8
- data/core/tests/behavior/async_compose.rs +297 -0
- data/core/tests/behavior/async_copy.rs +162 -1
- data/core/tests/behavior/async_delete.rs +364 -3
- data/core/tests/behavior/async_read.rs +86 -0
- data/core/tests/behavior/async_restore.rs +162 -0
- data/core/tests/behavior/async_stat.rs +90 -0
- data/core/tests/behavior/async_write.rs +330 -2
- data/core/tests/behavior/main.rs +4 -0
- data/core/upgrade.md +114 -1
- data/src/capability.rs +0 -1
- data/src/io.rs +0 -1
- data/src/lister.rs +0 -1
- data/src/metadata.rs +0 -1
- data/src/operator_info.rs +0 -1
- metadata +44 -2
|
@@ -15,80 +15,64 @@
|
|
|
15
15
|
// specific language governing permissions and limitations
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
|
-
//!
|
|
18
|
+
//! Implementing a layer.
|
|
19
19
|
//!
|
|
20
|
-
//!
|
|
20
|
+
//! A [`Layer`] intercepts an operator's composed service, operation context,
|
|
21
|
+
//! or both. Use a layer for behavior that applies across services, such as
|
|
22
|
+
//! retry, timeout, tracing, metrics, or runtime resource replacement.
|
|
21
23
|
//!
|
|
22
|
-
//!
|
|
23
|
-
//! service or its [`OperationContext`].
|
|
24
|
-
//! - Layer wrappers still implement typed [`Service`], so their own reader,
|
|
25
|
-
//! writer, lister, deleter, and copier bodies stay concrete.
|
|
26
|
-
//! - The composition boundary is [`Servicer`]. Boxing operation
|
|
27
|
-
//! bodies remains centralized in the blanket [`ServiceDyn`] implementation
|
|
28
|
-
//! for typed [`Service`] values.
|
|
24
|
+
//! # Two composition hooks
|
|
29
25
|
//!
|
|
30
|
-
//! [`Layer`]
|
|
31
|
-
//! default, so a layer only implements the plane it needs:
|
|
26
|
+
//! [`Layer`] exposes two hooks:
|
|
32
27
|
//!
|
|
33
|
-
//! ```
|
|
34
|
-
//!
|
|
35
|
-
//!
|
|
36
|
-
//!
|
|
37
|
-
//!
|
|
28
|
+
//! ```text
|
|
29
|
+
//! fn apply_service(&self, service: Servicer) -> Servicer;
|
|
30
|
+
//! fn apply_context(
|
|
31
|
+
//! &self,
|
|
32
|
+
//! service: Servicer,
|
|
33
|
+
//! context: OperationContext,
|
|
34
|
+
//! ) -> OperationContext;
|
|
38
35
|
//! ```
|
|
39
36
|
//!
|
|
40
|
-
//!
|
|
41
|
-
//!
|
|
42
|
-
//!
|
|
43
|
-
//!
|
|
44
|
-
//! to service operations.
|
|
37
|
+
//! `apply_service` wraps storage operations. `apply_context` wraps or replaces
|
|
38
|
+
//! runtime resources such as the HTTP transport and executor. Each hook
|
|
39
|
+
//! returns its input unchanged by default, so a layer implements only the
|
|
40
|
+
//! plane it owns.
|
|
45
41
|
//!
|
|
46
|
-
//!
|
|
42
|
+
//! The operator first applies every service hook in insertion order. It then
|
|
43
|
+
//! applies every context hook in the same order, passing the final service
|
|
44
|
+
//! stack to each context hook. Adding a layer or replacing the base context
|
|
45
|
+
//! replays the complete layer list, producing a service stack and context from
|
|
46
|
+
//! the same ordering.
|
|
47
47
|
//!
|
|
48
|
-
//!
|
|
49
|
-
//! `apply_service`.
|
|
50
|
-
//! - `XxxService` stores the inner [`Servicer`] and implements [`Service`].
|
|
48
|
+
//! # Operation layers
|
|
51
49
|
//!
|
|
52
|
-
//!
|
|
53
|
-
//! pub struct XxxLayer;
|
|
50
|
+
//! An operation layer normally contains:
|
|
54
51
|
//!
|
|
55
|
-
//!
|
|
56
|
-
//!
|
|
57
|
-
//!
|
|
58
|
-
//! }
|
|
59
|
-
//! }
|
|
60
|
-
//! ```
|
|
61
|
-
//!
|
|
62
|
-
//! Most operation layers only override the operations they need and forward the
|
|
63
|
-
//! rest to `inner`. This works because [`Servicer`] implements [`Service`] by
|
|
64
|
-
//! forwarding calls to [`ServiceDyn`], while the wrapper keeps concrete
|
|
65
|
-
//! operation body types until it is returned as a [`Servicer`].
|
|
52
|
+
//! - An `XxxLayer` that implements [`Layer::apply_service`].
|
|
53
|
+
//! - An `XxxService` that stores the inner [`Servicer`] and implements
|
|
54
|
+
//! [`Service`].
|
|
66
55
|
//!
|
|
67
|
-
//!
|
|
68
|
-
//! the
|
|
56
|
+
//! The wrapper overrides only the operations it owns and forwards the rest to
|
|
57
|
+
//! the inner service. It must also return capabilities that describe the
|
|
58
|
+
//! behavior of the wrapped stack. The wrapper keeps its own operation body
|
|
59
|
+
//! types concrete until OpenDAL erases it back into a [`Servicer`].
|
|
69
60
|
//!
|
|
70
|
-
//!
|
|
71
|
-
//! pub struct TransportLayer {
|
|
72
|
-
//! transport: HttpTransporter,
|
|
73
|
-
//! }
|
|
61
|
+
//! # Resource layers
|
|
74
62
|
//!
|
|
75
|
-
//!
|
|
76
|
-
//!
|
|
77
|
-
//!
|
|
78
|
-
//!
|
|
79
|
-
//!
|
|
80
|
-
//! ```
|
|
63
|
+
//! A resource-only layer implements [`Layer::apply_context`]. It should
|
|
64
|
+
//! preserve the previous resource when lower layers must remain effective. A
|
|
65
|
+
//! layer that wraps an HTTP transport or executor must decide explicitly
|
|
66
|
+
//! whether requests continue through the previous value or replace it
|
|
67
|
+
//! entirely.
|
|
81
68
|
//!
|
|
82
|
-
//! Layers that
|
|
83
|
-
//!
|
|
84
|
-
//!
|
|
85
|
-
//!
|
|
69
|
+
//! Layers that coordinate policy across operation and I/O phases can implement
|
|
70
|
+
//! both hooks. Shared mutable state requires interior mutability and must
|
|
71
|
+
//! remain `Send` and `Sync`, because cloned operators can run operations
|
|
72
|
+
//! concurrently.
|
|
86
73
|
//!
|
|
87
74
|
//! [`Layer`]: crate::raw::Layer
|
|
75
|
+
//! [`Layer::apply_service`]: crate::raw::Layer::apply_service
|
|
76
|
+
//! [`Layer::apply_context`]: crate::raw::Layer::apply_context
|
|
88
77
|
//! [`Service`]: crate::raw::Service
|
|
89
|
-
//! [`ServiceDyn`]: crate::raw::ServiceDyn
|
|
90
78
|
//! [`Servicer`]: crate::raw::Servicer
|
|
91
|
-
//! [`HttpTransporter`]: crate::HttpTransporter
|
|
92
|
-
//! [`Executor`]: crate::Executor
|
|
93
|
-
//! [`OperationContext`]: crate::raw::OperationContext
|
|
94
|
-
//! [`Operator`]: crate::Operator
|
|
@@ -17,37 +17,35 @@
|
|
|
17
17
|
|
|
18
18
|
//! The internal implementation details of OpenDAL.
|
|
19
19
|
//!
|
|
20
|
-
//!
|
|
20
|
+
//! This guide explains the extension boundaries used to implement OpenDAL
|
|
21
|
+
//! storage services and layers. Application code should use the public
|
|
22
|
+
//! [`Operator`] API; the raw APIs described here can change between minor
|
|
23
|
+
//! releases.
|
|
21
24
|
//!
|
|
22
|
-
//!
|
|
23
|
-
//!
|
|
24
|
-
//!
|
|
25
|
-
//! OpenDAL tries its best to keep the public API stable. But raw APIs
|
|
26
|
-
//! may change between minor releases from time to time. So most users
|
|
27
|
-
//! should only use the public API. Developers use raw APIs to implement
|
|
28
|
-
//! storage services or their own [`Layer`].
|
|
29
|
-
//!
|
|
30
|
-
//! In this section, we will talk about the following components:
|
|
31
|
-
//!
|
|
32
|
-
//! - [`Service`][accessor]: to connect underlying storage services.
|
|
33
|
-
//! - [`Layer`][layer]: middleware/interceptor between storage services.
|
|
34
|
-
//!
|
|
35
|
-
//! The relation between [`Service`], [`Layer`], [`Servicer`], [`OperationContext`],
|
|
36
|
-
//! and [`Operator`] looks like the following:
|
|
25
|
+
//! OpenDAL keeps service implementations typed until it composes them into an
|
|
26
|
+
//! operator:
|
|
37
27
|
//!
|
|
38
28
|
//! ```text
|
|
39
|
-
//!
|
|
40
|
-
//!
|
|
41
|
-
//!
|
|
42
|
-
//! └──────────────┘ │ + OperationContext resources │ └──────────────┘
|
|
43
|
-
//! └──────────────────────────────┘
|
|
29
|
+
//! Builder -> Service -> ServiceDyn -> Servicer -> Layer stack -> Operator
|
|
30
|
+
//! ^ |
|
|
31
|
+
//! +------ type erasure ------+
|
|
44
32
|
//! ```
|
|
45
33
|
//!
|
|
46
|
-
//! [`
|
|
34
|
+
//! - A [`Service`] implements storage operations and reports the capabilities
|
|
35
|
+
//! it provides.
|
|
36
|
+
//! - [`ServiceDyn`] is the object-safe boundary that erases a typed service
|
|
37
|
+
//! and its operation bodies.
|
|
38
|
+
//! - A [`Servicer`] is the shared, type-erased service handle stored by
|
|
39
|
+
//! operators and layers.
|
|
40
|
+
//! - A [`Layer`] wraps the service stack, the operation context, or both.
|
|
41
|
+
//!
|
|
42
|
+
//! Continue with [implementing a service][accessor] or
|
|
43
|
+
//! [implementing a layer][layer].
|
|
44
|
+
//!
|
|
47
45
|
//! [`Operator`]: crate::Operator
|
|
48
46
|
//! [`Service`]: crate::raw::Service
|
|
47
|
+
//! [`ServiceDyn`]: crate::raw::ServiceDyn
|
|
49
48
|
//! [`Servicer`]: crate::raw::Servicer
|
|
50
|
-
//! [`OperationContext`]: crate::raw::OperationContext
|
|
51
49
|
//! [`Layer`]: crate::raw::Layer
|
|
52
50
|
|
|
53
51
|
pub mod accessor;
|
data/core/core/src/docs/mod.rs
CHANGED
|
@@ -15,29 +15,33 @@
|
|
|
15
15
|
// specific language governing permissions and limitations
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
|
-
//!
|
|
18
|
+
//! OpenDAL contracts, Rust core guides, and historical project documents.
|
|
19
19
|
//!
|
|
20
|
-
//!
|
|
20
|
+
//! Start with [`concepts`] for the Rust core API model. [`specs`] defines the
|
|
21
|
+
//! current portable contracts implemented by OpenDAL. Service and layer authors
|
|
22
|
+
//! can continue with [`internals`], while [`performance`] covers application
|
|
23
|
+
//! tuning. Accepted RFCs in [`rfcs`] preserve the decisions and context that
|
|
24
|
+
//! led to current designs.
|
|
21
25
|
|
|
22
26
|
#![allow(rustdoc::bare_urls)]
|
|
23
27
|
|
|
24
|
-
pub mod comparisons;
|
|
25
|
-
|
|
26
28
|
pub mod concepts;
|
|
27
|
-
|
|
28
29
|
pub mod internals;
|
|
29
|
-
|
|
30
30
|
pub mod performance;
|
|
31
|
+
pub mod specs;
|
|
31
32
|
|
|
32
33
|
/// Changes log for all OpenDAL released versions.
|
|
33
34
|
#[doc = include_str!("../../../CHANGELOG.md")]
|
|
34
35
|
#[cfg(not(doctest))]
|
|
36
|
+
#[allow(rustdoc::broken_intra_doc_links, rustdoc::invalid_rust_codeblocks)]
|
|
35
37
|
pub mod changelog {}
|
|
36
38
|
|
|
37
39
|
#[cfg(not(doctest))]
|
|
40
|
+
#[allow(rustdoc::broken_intra_doc_links, rustdoc::invalid_rust_codeblocks)]
|
|
38
41
|
pub mod rfcs;
|
|
39
42
|
|
|
40
43
|
/// Upgrade and migrate procedures while OpenDAL meets breaking changes.
|
|
41
44
|
#[doc = include_str!("upgrade.md")]
|
|
42
45
|
#[cfg(not(doctest))]
|
|
46
|
+
#[allow(rustdoc::broken_intra_doc_links, rustdoc::invalid_rust_codeblocks)]
|
|
43
47
|
pub mod upgrade {}
|
|
@@ -1,101 +1,138 @@
|
|
|
1
|
-
# Concurrent
|
|
1
|
+
# Concurrent Writes
|
|
2
2
|
|
|
3
|
-
OpenDAL writes
|
|
3
|
+
OpenDAL writes parts sequentially by default. This keeps memory and request
|
|
4
|
+
pressure low, but one in-flight request often cannot fill the available
|
|
5
|
+
bandwidth on a high-latency path.
|
|
4
6
|
|
|
5
7
|
```rust
|
|
6
|
-
# use
|
|
7
|
-
# async fn
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
# use opendal_core::{Buffer, Operator, Result};
|
|
9
|
+
# async fn write_sequentially(
|
|
10
|
+
# op: &Operator,
|
|
11
|
+
# first: Buffer,
|
|
12
|
+
# second: Buffer,
|
|
13
|
+
# ) -> Result<()> {
|
|
14
|
+
let mut writer = op.writer("large-object.bin").await?;
|
|
15
|
+
writer.write(first).await?;
|
|
16
|
+
writer.write(second).await?;
|
|
17
|
+
writer.close().await?;
|
|
18
|
+
# Ok(())
|
|
12
19
|
# }
|
|
13
20
|
```
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
Set `concurrent` above `1` to let services with multipart or block-based write
|
|
23
|
+
support upload independent parts in parallel:
|
|
16
24
|
|
|
17
25
|
```rust
|
|
18
|
-
# use
|
|
19
|
-
# async fn
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
# use opendal_core::{Buffer, Operator, Result};
|
|
27
|
+
# async fn write_concurrently(
|
|
28
|
+
# op: &Operator,
|
|
29
|
+
# first: Buffer,
|
|
30
|
+
# second: Buffer,
|
|
31
|
+
# ) -> Result<()> {
|
|
32
|
+
let mut writer = op
|
|
33
|
+
.writer_with("large-object.bin")
|
|
22
34
|
.concurrent(8)
|
|
23
35
|
.await?;
|
|
24
36
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
writer.write(first).await?;
|
|
38
|
+
writer.write(second).await?;
|
|
39
|
+
writer.close().await?;
|
|
40
|
+
# Ok(())
|
|
28
41
|
# }
|
|
29
42
|
```
|
|
30
43
|
|
|
31
|
-
|
|
44
|
+
For multipart and block writers, OpenDAL schedules part uploads through its
|
|
45
|
+
[`Executor`][crate::Executor] and tracks their results in a task queue. A write
|
|
46
|
+
call can return while earlier parts are still in flight when the queue has
|
|
47
|
+
capacity. [`Writer::close`][crate::Writer::close] drains the queue and performs
|
|
48
|
+
the final commit, so applications must always check the result from `close`.
|
|
32
49
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
50
|
+
The storage service determines the native mechanism. S3 uses multipart upload,
|
|
51
|
+
while Azure Blob uses block upload. Services without a concurrent write path
|
|
52
|
+
continue to execute sequentially even when the option is present. Check
|
|
53
|
+
[`Capability::write_can_multi`][crate::Capability::write_can_multi] before
|
|
54
|
+
tuning multipart or block writes.
|
|
38
55
|
|
|
39
56
|
## Tuning
|
|
40
57
|
|
|
41
|
-
|
|
58
|
+
Concurrent writes have two controls:
|
|
42
59
|
|
|
43
|
-
- `concurrent
|
|
44
|
-
|
|
60
|
+
- `concurrent` is the maximum number of part uploads OpenDAL attempts to keep
|
|
61
|
+
in flight. The default is `1`, and values below `1` are normalized to `1`.
|
|
62
|
+
- `chunk` is the target size of each part. Its default and valid range depend on
|
|
63
|
+
the service.
|
|
45
64
|
|
|
46
65
|
### `concurrent`
|
|
47
66
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
The best value for `concurrent` depends on the specific use case and the underlying storage service. In general, a higher value can lead to better performance, but it highly depends on the storage service and the network conditions. For example, if the storage service is robust and bandwidth is sufficient, you may observe a linear increase in performance with higher `concurrent` values. However, if the storage service has request limits or the network is nearly saturated, increasing `concurrent` may not lead to any performance improvement—and could even degrade performance due to infinite retries on errors.
|
|
67
|
+
`concurrent` is an upper bound, not a guaranteed level. Setting it to `8` does
|
|
68
|
+
not create eight active requests unless the input arrives quickly enough and
|
|
69
|
+
the object contains enough parts. Object size, request latency, and service
|
|
70
|
+
support can all reduce the observed concurrency.
|
|
53
71
|
|
|
54
|
-
|
|
72
|
+
Start with `2` or `4`, then try `8` while measuring the real workload. Higher
|
|
73
|
+
concurrency can improve bandwidth utilization, but it also increases in-flight
|
|
74
|
+
requests, buffered data, and pressure on service request limits. Once the
|
|
75
|
+
network or service is saturated, increasing it further can reduce throughput by
|
|
76
|
+
causing throttling and retries.
|
|
55
77
|
|
|
56
78
|
### `chunk`
|
|
57
79
|
|
|
58
|
-
|
|
80
|
+
OpenDAL buffers small writes until it can form a part of the configured size.
|
|
81
|
+
This avoids issuing one storage request for every small input buffer. The final
|
|
82
|
+
part may be smaller.
|
|
59
83
|
|
|
60
|
-
|
|
84
|
+
Larger chunks reduce request count and per-request overhead, but use more memory
|
|
85
|
+
per in-flight part and require more data to be retried after a failed upload.
|
|
86
|
+
Smaller chunks begin parallel work sooner, but increase request rate and may be
|
|
87
|
+
invalid for the service. For example, S3 multipart upload has a 5 MiB minimum
|
|
88
|
+
part size; OpenDAL raises smaller configured values to the service minimum.
|
|
61
89
|
|
|
62
|
-
|
|
90
|
+
Inspect [`Capability::write_multi_min_size`][crate::Capability::write_multi_min_size]
|
|
91
|
+
and [`Capability::write_multi_max_size`][crate::Capability::write_multi_max_size]
|
|
92
|
+
before overriding the service default. For large object-storage uploads, 8 MiB
|
|
93
|
+
is a useful starting point, followed by measurements at the expected object
|
|
94
|
+
sizes and concurrency.
|
|
63
95
|
|
|
64
|
-
|
|
96
|
+
## One-shot and adapter APIs
|
|
65
97
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
To upload a large in-memory chunk concurrently:
|
|
98
|
+
`write_with` can split one in-memory buffer into concurrent parts:
|
|
69
99
|
|
|
70
100
|
```rust
|
|
71
|
-
# use
|
|
72
|
-
# async fn
|
|
73
|
-
let
|
|
74
|
-
|
|
101
|
+
# use opendal_core::{Buffer, Operator, Result};
|
|
102
|
+
# async fn upload(op: &Operator, data: Buffer) -> Result<()> {
|
|
103
|
+
let _metadata = op
|
|
104
|
+
.write_with("large-object.bin", data)
|
|
105
|
+
.chunk(8 * 1024 * 1024)
|
|
106
|
+
.concurrent(4)
|
|
107
|
+
.await?;
|
|
108
|
+
# Ok(())
|
|
75
109
|
# }
|
|
76
110
|
```
|
|
77
111
|
|
|
78
|
-
|
|
112
|
+
A configured writer keeps the same chunking and concurrency behavior after it
|
|
113
|
+
is converted with [`Writer::into_sink`][crate::Writer::into_sink],
|
|
114
|
+
[`Writer::into_bytes_sink`][crate::Writer::into_bytes_sink], or
|
|
115
|
+
[`Writer::into_futures_async_write`][crate::Writer::into_futures_async_write].
|
|
79
116
|
|
|
80
117
|
```rust
|
|
81
118
|
use std::io;
|
|
82
119
|
|
|
83
|
-
use bytes::Bytes;
|
|
84
120
|
use futures::SinkExt;
|
|
85
|
-
use
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
.
|
|
91
|
-
.concurrent(
|
|
92
|
-
.chunk(256)
|
|
121
|
+
use opendal_core::{Buffer, Operator};
|
|
122
|
+
|
|
123
|
+
async fn upload_with_sink(op: Operator, data: Buffer) -> io::Result<()> {
|
|
124
|
+
let mut sink = op
|
|
125
|
+
.writer_with("large-object.bin")
|
|
126
|
+
.chunk(8 * 1024 * 1024)
|
|
127
|
+
.concurrent(4)
|
|
93
128
|
.await?
|
|
94
129
|
.into_sink();
|
|
95
|
-
let bs = "Hello, World!".as_bytes();
|
|
96
|
-
w.send(Buffer::from(bs)).await?;
|
|
97
|
-
w.close().await?;
|
|
98
130
|
|
|
131
|
+
sink.send(data).await?;
|
|
132
|
+
sink.close().await?;
|
|
99
133
|
Ok(())
|
|
100
134
|
}
|
|
101
135
|
```
|
|
136
|
+
|
|
137
|
+
Measure end-to-end throughput and completion latency together with peak memory,
|
|
138
|
+
request count, retries, throttling, and the result from the final close.
|