You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2024/05/23 16:08:28 UTC
(opendal) branch rfc-executor created (now 308ee9b50b)
This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a change to branch rfc-executor
in repository https://gitbox.apache.org/repos/asf/opendal.git
at 308ee9b50b feat: Executor
This branch includes the following new commits:
new 308ee9b50b feat: Executor
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(opendal) 01/01: feat: Executor
Posted by xu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch rfc-executor
in repository https://gitbox.apache.org/repos/asf/opendal.git
commit 308ee9b50b8e76291b82e907d5cce165b633dc03
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Fri May 24 00:07:53 2024 +0800
feat: Executor
Signed-off-by: Xuanwo <gi...@xuanwo.io>
---
core/src/docs/rfcs/0000_executor.md | 114 ++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/core/src/docs/rfcs/0000_executor.md b/core/src/docs/rfcs/0000_executor.md
new file mode 100644
index 0000000000..333380bc9d
--- /dev/null
+++ b/core/src/docs/rfcs/0000_executor.md
@@ -0,0 +1,114 @@
+- Proposal Name: `executor`
+- Start Date: 2024-05-23
+- RFC PR: [apache/opendal#0000](https://github.com/apache/opendal/pull/0000)
+- Tracking Issue: [apache/opendal#0000](https://github.com/apache/opendal/issues/0000)
+
+# Summary
+
+Add executor in opendal to allow running tasks concurrently in background.
+
+# Motivation
+
+OpenDAL offers top-tier support for concurrent execution, allowing tasks to run simultaneously in the background. Users can easily enable concurrent file read/write operations with just one line of code:
+
+```diff
+ let w = op
+ .writer_with(path)
+ .chunk(8 * 1024 * 1024) // 8 MiB per chunk
++ .concurrent(16) // 16 concurrent tasks
+ .await?;
+```
+
+However, the execution of those tasks relies on users continuously calling `write`. They cannot run tasks concurrently in the background. (I explained the technical details in the `Rationale and alternatives` section.)
+
+This can result in the following issues:
+
+- Task latency may increase as tasks are not executed until the task queue is full.
+- Memory usage may be high because all chunks must be held in memory until the task is completed.
+
+I propose introducing an executor in OpenDAL to enable concurrent background task execution. The executor will autonomously manage the tasks without requiring user intervention for progress.
+
+# Guide-level explanation
+
+OpenDAL will add a new `Executor` struct to manage concurrent tasks.
+
+```rust
+pub struct Executor {
+ ...
+}
+
+impl Executor {
+ /// Create a new tokio based executor.
+ pub fn new() -> Self { ... }
+
+ /// Create a new executor with given execute impl.
+ pub fn with(exec: Arc<dyn Execute>) -> Self { ... }
+
+ /// Run given future in background immediately.
+ pub fn execute<F>(&self, f: F) -> RemoteHandle<F::Output>
+ where
+ F: Future + Send + 'static,
+ {
+ ...
+ }
+}
+```
+
+The `Executor` uses the `tokio` runtime by default but users can also provide their own runtime by:
+
+```rust
+pub trait Execute {
+ fn execute<F>(&self, f: BoxedFuture<()>) -> Result<()>;
+}
+```
+
+Users can set executor in `OpWrite` / `OpRead` to enable concurrent background task execution:
+
+```rust
++ let exec = Executor::new();
+ let w = op
+ .writer_with(path)
+ .chunk(8 * 1024 * 1024) // 8 MiB per chunk
+ .concurrent(16) // 16 concurrent tasks
++ .executor(exec) // Use specfied executor
+ .await?;
+```
+
+Specifying an executor every time is cumbersome. Users can also set a global executor for given operator:
+
+```rust
++ let exec = Executor::new();
++ let op = op.with_default_executor(exec);
+
+ let w = op
+ .writer_with(path)
+ .chunk(8 * 1024 * 1024) // 8 MiB per chunk
+ .concurrent(16) // 16 concurrent tasks
+ .await?;
+```
+
+# Reference-level explanation
+
+# Drawbacks
+
+# Rationale and alternatives
+
+## Why `ConcurrentFutures` doesn't work?
+
+# Prior art
+
+# Unresolved questions
+
+# Future possibilities
+
+## Blocking Executor
+
+This proposal mainly focuses on async tasks. However, we can also consider adding blocking support to `Executor`. Users can use concurrent tasks in blocking context too:
+
+```rust
+ let w = op
+ .writer_with(path)
+ .chunk(8 * 1024 * 1024) // 8 MiB per chunk
++ .concurrent(16) // 16 concurrent tasks
+ .do()?;
+```