Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple connections & threads from a single process #378

Closed
dowusu opened this issue Sep 3, 2024 · 5 comments
Closed

Multiple connections & threads from a single process #378

dowusu opened this issue Sep 3, 2024 · 5 comments

Comments

@dowusu
Copy link

dowusu commented Sep 3, 2024

I tried wrapping Connection with Arc in order to use it across multiple thread only to run into an error, InnerConnection is wrapped in a RefCell.

Per the duckdb docs, multiple reads and writes should be possible from a single process, the python lib allows that and I was wondering if there's a way to achieve this.

My current implementation involves creating a database with Connection::open("file_name") and subsequently calling this same function within each thread; it didn't work as I kept getting an error of the file being used by an existing process.

Is there something I'm missing? my current option to use channel mpsc where the consumer will hold a connection to the database and do the insertion from the producers within the multiple threads.

Thank you for the great work.

@era127
Copy link
Contributor

era127 commented Sep 26, 2024

Unfortunately the rust client api does not separate the Connection and Database types and this is not straightforward. Instead you could use an arc mutex of a connection and use try_clone() to make a new connection within a thread. Otherwise you could use a deadpool of connections and populate the pool by cloning the connection using try_clone() on the initial connection.

@dowusu
Copy link
Author

dowusu commented Sep 27, 2024

I will do a POC per your pointers and share my findings. Thank you.

@dowusu dowusu closed this as completed Sep 27, 2024
@dvic
Copy link

dvic commented Nov 7, 2024

@dowusu care to sure your findings? What worked in the end the best for you?

@dowusu
Copy link
Author

dowusu commented Nov 8, 2024

I ended up with something that looks like the below; btw try_clone works as advertised & I replaced my channel implementation which serialises access to duckdb on a single thread with multiple connection.

pub struct MemCache {
    conn: Connection,
    conf: PrestoSettings,
}

impl MemCache {
    pub fn new(conf: PrestoSettings) -> Result<Self> {
        let conn = Connection::open_in_memory()?;
        info!("Creating an in-memory database.");

        Ok(Self { conn, conf })
    }
    
      pub fn get_connection(&self) -> Result<Connection> {
        self.conn.try_clone()
       }
    }

Usage was along these lines

let db = MemCache::new(config);

for i in 0..10 {
    let conn = db.get_connection().expect("Handle the error, I've not had a single failure");
    thread::spawn(move || {
       // you can work with the connection object/struct
   });
}

I hope this helps. Thank you.

@dvic
Copy link

dvic commented Nov 8, 2024

I ended up with something that looks like the below; btw try_clone works as advertised & I replaced my channel implementation which serialises access to duckdb on a single thread with multiple connection.

pub struct MemCache {
    conn: Connection,
    conf: PrestoSettings,
}

impl MemCache {
    pub fn new(conf: PrestoSettings) -> Result<Self> {
        let conn = Connection::open_in_memory()?;
        info!("Creating an in-memory database.");

        Ok(Self { conn, conf })
    }
    
      pub fn get_connection(&self) -> Result<Connection> {
        self.conn.try_clone()
       }
    }

Usage was along these lines

let db = MemCache::new(config);

for i in 0..10 {
    let conn = db.get_connection().expect("Handle the error, I've not had a single failure");
    thread::spawn(move || {
       // you can work with the connection object/struct
   });
}

I hope this helps. Thank you.

Nice! Thanks for the reply!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants