-
Notifications
You must be signed in to change notification settings - Fork 78
Concurrency #44
Comments
@theduke , the |
Ah, I realized that I can open multiple file handles and then use them concurrently. Since zbox does support internal concurrency/locking, it would be quite nice to hoist all of this into the |
In my opinion, |
|
It seems to fail to support working on multiple files even without threads. I get
|
Can you share your code about this issue? One |
fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
zbox::init_env();
use std::io::Write;
let mut r = zbox::RepoOpener::new().create(true).force(true).open("file:///tmp/limit/q", "qwe123")?;
eprintln!("Opening file1");
let mut f1 = r.create_file("/test1")?;
eprintln!("Opening file2");
let mut f2 = r.create_file("/test2")?;
eprintln!("Writing file1");
f1.write_all(b"12345")?;
eprintln!("Writing file2");
f2.write_all(b"qwerty")?;
eprintln!("Committing file1");
f1.finish()?;
eprintln!("Committing file2");
f2.finish()?;
Ok(())
}
|
Thanks @vi for your code. |
Is it a bug or by design? |
Well, it is by design currently but I think a tx should not hold a shared object too long until |
Can two If no then it should be documented. |
Ok, after digging through this issue deeper I found it is actually not the exclusive access to content manager caused this issue, sorry about my misleading explanation before. The real reason is that each thread can only run one transaction at a time. In the code below, let mut r = zbox::RepoOpener::new().create(true).force(true).open("file:///tmp/limit/q", "qwe123")?;
let mut f1 = r.create_file("/test1")?;
let mut f2 = r.create_file("/test2")?;
f1.write_all(b"12345")?; // this will create one ongoing tx
f2.write_all(b"qwerty")?; // this will create another ongoing tx
f1.finish()?;
f2.finish()?; There are 2 files are using multi-part writing, 2
f1.write_all(b"12345")?;
f1.finish()?;
f2.write_all(b"qwerty")?;
f2.finish()?;
let child1 = std::thread::spawn(move || {
f1.write_all(b"12345").unwrap();
f1.finish().unwrap();
});
let child2 = std::thread::spawn(move || {
f2.write_all(b"qwerty").unwrap();
f2.finish().unwrap();
});
child1.join().unwrap();
child2.join().unwrap(); |
Is ZboxFS supposed to be used in async/Tokio context? (where thread may be unpredictable). Does it rely on thread-local storage? Can transactions be untied from threads? There can be explicit object Or is there some definite way to check if it is OK to write a file? (when running from thread pool where tasks can migrate between threads on its own) |
It hasn't used async yet because that is a big change and may change the internal structure as well.
Yes, it stores tx id in thread local storage.
Currently, threading is tightly coupled with tx control internally, so it is hard to expose it as API and get it right. Also, this will add complexity for developing using ZboxFS. As for the thread pool use case, I think app has to stick each file to different thread at this moment. If app cannot control that, it might be a limitation of ZboxFS. |
It seems like zbox does not currently allow for any multi-threaded concurrency at all.
Sadly this limits usage to very simple use cases.
Are there plans for introducing concurrency?
A "simple" first step could be to allow concurrent reads, with a global write lock. Although I'd really love to have concurrent reads and writes as well.
The text was updated successfully, but these errors were encountered: