From 5aa1b62fafc20424cf3d4052f60e69a4e7e62597 Mon Sep 17 00:00:00 2001 From: Thijs Cadier Date: Sun, 4 Oct 2015 13:30:45 +0200 Subject: [PATCH] Use an Arc to share ClientPool between threads --- src/client.rs | 44 +++++++++++++++++--------------------------- tests/client.rs | 3 ++- tests/cursor.rs | 3 ++- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/client.rs b/src/client.rs index f8ce7a0..98f1dcb 100644 --- a/src/client.rs +++ b/src/client.rs @@ -20,14 +20,18 @@ use super::database::Database; use super::uri::Uri; use super::read_prefs::ReadPrefs; -// TODO: We're using a sort of poor man's Arc here -// with this root bool, there must be a better way. +/// Client pool to a MongoDB cluster. +/// +/// This client pool cannot be cloned, but it can be shared between threads by using an `Arc`. +/// Use the pool to pop a client and do operations. The client will be automatically added +/// back to the pool when it goes out of scope. +/// +/// See: http://api.mongodb.org/c/current/mongoc_client_pool_t.html pub struct ClientPool { - root_instance: bool, - // Uri and SslOptions need to be present for the - // lifetime of this pool. + // Uri and SslOptions need to be present for the lifetime of this pool otherwise the C driver + // loses access to resources it needs. uri: Uri, - ssl_options: Option, + _ssl_options: Option, inner: *mut bindings::mongoc_client_pool_t } @@ -55,10 +59,9 @@ impl ClientPool { None => () }; ClientPool { - root_instance: true, - uri: uri, - ssl_options: ssl_options, - inner: pool + uri: uri, + _ssl_options: ssl_options, + inner: pool } } @@ -82,6 +85,7 @@ impl ClientPool { /// See: http://api.mongodb.org/c/current/mongoc_client_pool_push.html unsafe fn push(&self, mongo_client: *mut bindings::mongoc_client_t) { assert!(!self.inner.is_null()); + assert!(!mongo_client.is_null()); bindings::mongoc_client_pool_push( self.inner, mongo_client @@ -98,25 +102,11 @@ impl fmt::Debug for ClientPool { } } -impl Clone for ClientPool { - fn clone(&self) -> ClientPool { - assert!(!self.inner.is_null()); - ClientPool { - root_instance: false, - uri: self.uri.clone(), - ssl_options: self.ssl_options.clone(), - inner: self.inner.clone() - } - } -} - impl Drop for ClientPool { fn drop(&mut self) { - if self.root_instance { - assert!(!self.inner.is_null()); - unsafe { - bindings::mongoc_client_pool_destroy(self.inner); - } + assert!(!self.inner.is_null()); + unsafe { + bindings::mongoc_client_pool_destroy(self.inner); } } } diff --git a/tests/client.rs b/tests/client.rs index 792f8d3..9959ef5 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -1,5 +1,6 @@ use std::env; use std::path::PathBuf; +use std::sync::Arc; use std::thread; use mongo_driver::uri::Uri; @@ -51,7 +52,7 @@ fn test_new_pool_pop_client_and_take_database_and_collection() { #[test] fn test_new_pool_and_pop_client_in_threads() { let uri = Uri::new("mongodb://localhost:27017/").unwrap(); - let pool = ClientPool::new(uri, None); + let pool = Arc::new(ClientPool::new(uri, None)); let pool1 = pool.clone(); let guard1 = thread::spawn(move || { diff --git a/tests/cursor.rs b/tests/cursor.rs index 382fb5d..d12876b 100644 --- a/tests/cursor.rs +++ b/tests/cursor.rs @@ -1,3 +1,4 @@ +use std::sync::Arc; use std::thread; use bson; @@ -34,7 +35,7 @@ fn test_tailing_cursor() { // See: http://api.mongodb.org/c/1.1.8/cursors.html#tailable let uri = Uri::new("mongodb://localhost:27017/").unwrap(); - let pool = ClientPool::new(uri, None); + let pool = Arc::new(ClientPool::new(uri, None)); let client = pool.pop(); let database = client.get_database("rust_test"); database.get_collection("capped").drop().unwrap_or(());