Giter Club home page Giter Club logo

r2d2's Introduction

r2d2

CircleCI

A generic connection pool for Rust.

Documentation

Opening a new database connection every time one is needed is both inefficient and can lead to resource exhaustion under high traffic conditions. A connection pool maintains a set of open connections to a database, handing them out for repeated use.

r2d2 is agnostic to the connection type it is managing. Implementors of the ManageConnection trait provide the database-specific logic to create and check the health of connections.

A (possibly not exhaustive) list of adaptors for different backends:

Backend Adaptor Crate
rust-postgres r2d2-postgres
redis-rs use r2d2 feature of redis-rs
rust-memcache r2d2-memcache
rust-mysql-simple r2d2-mysql
rusqlite r2d2-sqlite
rsfbclient r2d2-firebird
rusted-cypher r2d2-cypher
diesel diesel::r2d2 (docs)
couchdb r2d2-couchdb
mongodb (archived)
use official mongodb driver instead
r2d2-mongodb
(deprecated: official driver handles pooling internally)
odbc r2d2-odbc
jfs r2d2-jfs
oracle r2d2-oracle
ldap3 r2d2-ldap
duckdb-rs use r2d2 feature of duckdb-rs

Example

Using an imaginary "foodb" database.

use std::thread;

extern crate r2d2;
extern crate r2d2_foodb;

fn main() {
    let manager = r2d2_foodb::FooConnectionManager::new("localhost:1234");
    let pool = r2d2::Pool::builder()
        .max_size(15)
        .build(manager)
        .unwrap();

    for _ in 0..20 {
        let pool = pool.clone();
        thread::spawn(move || {
            let conn = pool.get().unwrap();
            // use the connection
            // it will be returned to the pool when it falls out of scope.
        })
    }
}

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.

r2d2's People

Contributors

aisk avatar alexcrichton avatar behnam avatar ben-ph avatar bitcapybara avatar borisfaure avatar c0dearm avatar codyps avatar couchand avatar dependabot-preview[bot] avatar dependabot[bot] avatar flarp avatar flosse avatar frisoft avatar iterion avatar johntitor avatar lnagyatatlassian avatar mariuz avatar name1e5s avatar nottxy avatar paolobarbolini avatar petoknm avatar reticenceji avatar rursprung avatar rushmorem avatar scorphus avatar sfackler avatar sgrif avatar uvd avatar wangfenjin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

r2d2's Issues

Unsure how to deal with the removal of `r2d2::Config`

Sorry to ask here, I'm not sure where a better place to ask is (there's no IRC or gitter link in the README)... crates.io has this function which I am completely stumped on how to migrate to 0.8.0. Any help would be appreciated.

pub fn diesel_pool(
    url: &str,
    config: r2d2::Config<PgConnection, r2d2_diesel::Error>,
) -> DieselPool {
    let mut url = Url::parse(url).expect("Invalid database URL");
    if env::var("HEROKU").is_ok() && !url.query_pairs().any(|(k, _)| k == "sslmode") {
        url.query_pairs_mut().append_pair("sslmode", "require");
    }
    let manager = ConnectionManager::new(url.into_string());
    r2d2::Pool::new(config, manager).unwrap()
}

Pool should implement `RefUnwindSafe`

All types which are Sync should also implement RefUnwindSafe as the former implies the latter. Currently the Pool type is not RefUnwindSafe (through no fault of its own) because it stores a Condvar, and Condvar is also (incorrectly) missing a RefUnwindSafe implementation in the rust standard library.

However, r2d2 could explicitly provide this implementation.

Resize connection pool at runtime

Hi,

First: Great and very easy to use crate! Thanks for that!
This more a question than a issue: Is it possible to resize the pool without loosing the established connections? Of course I could build a new pool but this would result in dropping of all the already established connections. In my use case I'd like to initialise the pool with a small number of connections because of timing restrictions (without disabling the fail fast feature in order to get instant feedback) and increase the size later as needed up to a certain limit.
Don't know if it is important: I use the r2d2 Redis crate.

Thanks,

@flxo

Can I use it on cassandra?

Because I did not see information about cassandra on the list, so if i want to build like Sql, is there a related way?

`diesel::connection::Connection` is not implemented for `diesel::PgConnection`

I am currently trying to follow the rocket guide and implement a PgConnection in between api endpoints.

I have the following code, which was working before I updated to the newest version (I already adapted the function init_pool following the changelog:

use diesel;
use diesel::prelude::*;
use r2d2_diesel::ConnectionManager;
use r2d2;
use types;
use time;

use std::ops::Deref;
use rocket::http::Status;
use rocket::request::{self, FromRequest};
use rocket::{Request, State, Outcome};

type Pool = r2d2::Pool<ConnectionManager<PgConnection>>;

pub struct DbConn(pub r2d2::PooledConnection<ConnectionManager<PgConnection>>);

impl<'a, 'r> FromRequest<'a, 'r> for DbConn {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> request::Outcome<DbConn, ()> {
        let pool = request.guard::<State<Pool>>()?;
        match pool.get() {
            Ok(conn) => Outcome::Success(DbConn(conn)),
            Err(_) => Outcome::Failure((Status::ServiceUnavailable, ()))
        }
    }
}

// For the convenience of using an &DbConn as an &SqliteConnection.
impl Deref for DbConn {
    type Target = PgConnection;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

/**
Initialize a database pool
*/
pub fn init_pool() -> Pool {
    let manager = ConnectionManager::<PgConnection>::new(DATABASE_URL);
    let pool = r2d2::Pool::builder()
        .build(manager).expect("db pool");
    pool
}

However, I get the following weird error.

error[E0277]: the trait bound `diesel::PgConnection: diesel::connection::Connection` is not satisfied
  --> src/database_worker.rs:26:19
   |
26 | pub struct DbConn(pub r2d2::PooledConnection<ConnectionManager<PgConnection>>);
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::connection::Connection` is not implemented for `diesel::PgConnection`
   |
   = note: required because of the requirements on the impl of `r2d2::ManageConnection` for `r2d2_diesel::ConnectionManager<diesel::PgConnection>`
   = note: required by `r2d2::PooledConnection`

error[E0277]: the trait bound `diesel::PgConnection: diesel::connection::Connection` is not satisfied
  --> src/database_worker.rs:52:1
   |
52 | / pub fn init_pool() -> Pool {
53 | |     let manager = ConnectionManager::<PgConnection>::new(DATABASE_URL);
54 | |     let pool = r2d2::Pool::builder()
55 | |         .build(manager).expect("db pool");
56 | |     pool
57 | | }
   | |_^ the trait `diesel::connection::Connection` is not implemented for `diesel::PgConnection`
   |
   = note: required because of the requirements on the impl of `r2d2::ManageConnection` for `r2d2_diesel::ConnectionManager<diesel::PgConnection>`
   = note: required by `r2d2::Pool`

error: aborting due to 2 previous errors

Any idea why I get these errors? This also seems to work for Sqlite, but not for PgConnection apparently.

Relicense under dual MIT/Apache-2.0

This issue was automatically generated. Feel free to close without ceremony if
you do not agree with re-licensing or if it is not possible for other reasons.
Respond to @cmr with any questions or concerns, or pop over to
#rust-offtopic on IRC to discuss.

You're receiving this because someone (perhaps the project maintainer)
published a crates.io package with the license as "MIT" xor "Apache-2.0" and
the repository field pointing here.

TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that
license is good for interoperation. The MIT license as an add-on can be nice
for GPLv2 projects to use your code.

Why?

The MIT license requires reproducing countless copies of the same copyright
header with different names in the copyright field, for every MIT library in
use. The Apache license does not have this drawback. However, this is not the
primary motivation for me creating these issues. The Apache license also has
protections from patent trolls and an explicit contribution licensing clause.
However, the Apache license is incompatible with GPLv2. This is why Rust is
dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for
GPLv2 compat), and doing so would be wise for this project. This also makes
this crate suitable for inclusion and unrestricted sharing in the Rust
standard distribution and other projects using dual MIT/Apache, such as my
personal ulterior motive, the Robigalia project.

Some ask, "Does this really apply to binary redistributions? Does MIT really
require reproducing the whole thing?" I'm not a lawyer, and I can't give legal
advice, but some Google Android apps include open source attributions using
this interpretation. Others also agree with
it
.
But, again, the copyright notice redistribution is not the primary motivation
for the dual-licensing. It's stronger protections to licensees and better
interoperation with the wider Rust ecosystem.

How?

To do this, get explicit approval from each contributor of copyrightable work
(as not all contributions qualify for copyright, due to not being a "creative
work", e.g. a typo fix) and then add the following to your README:

## License

Licensed under either of

 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.

and in your license headers, if you have them, use the following boilerplate
(based on that used in Rust):

// Copyright 2016 r2d2 Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

It's commonly asked whether license headers are required. I'm not comfortable
making an official recommendation either way, but the Apache license
recommends it in their appendix on how to use the license.

Be sure to add the relevant LICENSE-{MIT,APACHE} files. You can copy these
from the Rust repo for a plain-text
version.

And don't forget to update the license metadata in your Cargo.toml to:

license = "MIT OR Apache-2.0"

I'll be going through projects which agree to be relicensed and have approval
by the necessary contributors and doing this changes, so feel free to leave
the heavy lifting to me!

Contributor checkoff

To agree to relicensing, comment with :

I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option.

Or, if you're a contributor, you can check the box in this repo next to your
name. My scripts will pick this exact phrase up and check your checkbox, but
I'll come through and manually review this issue later as well.

min_size priority

Hi.

min_idle and max_lifetime or idle_timeout are how prioritize?

Q: Set to 10 min_idle and set 10 secs to max_lifetime and then after 10 secs...
A1: kill 10 connections, and then create new connections for keep min_idle
A2: ignore max_lifetime for keep min_idle

Q: Set to 10 min_idle and set 10 secs to idle_timeout and then after 10 secs all connections are idle...
A1: kill 10 connections, and then create new connections for keep min_idle
A2: ignore idle_timeout for keep min_idle

Which answer is correct? Or another?

Could ScheduledThreadPool be shared between Pool?

There are many Databases(300 Hundreds of...) need be connected...

There is one ScheduledThreadPool for one Pool, and one ScheduledThreadPool will start 3 threads by default, then there will be about 900 threads started...

It is huge...

So, If the ScheduledThreadPool could be shared between Pool, then that would be great

Ability to reset connection pool?

Hi! I'm currently looking into using r2d2 for the connection pooling in the MongoDB Rust driver, and I've hit a minor roadblock with regards to be able to reset the connection pool in the case that the topology changes. Specifically, the driver uses a background thread per server to monitor the state of the topology, and if one of the monitoring threads loses the ability to connect to a server, then the driver needs to refresh all connections in the pool to establish the new topology. As far as I can tell, r2d2 doesn't currently provide this functionality publicly, although it appears that there's some functionality for it internally. Is there any chance that an ability to reset the connection pool could be made public in some form? I'd be happy to contribute a pull request if you're open to this idea but don't have the time to work on it.

How to catch and handle connection issues?

I have two cases where I would like to catch and handle the fact that my DB is down.

  1. When the application starts up I want to throw an error an exist
  2. During a Request, I want to return an error saying the DB is down.

In both cases, as far as I can tell, there is no way for me to catch the error and gracefully handle it.

let manager = PostgresConnectionManager::new(config.db_uri.unwrap(), TlsMode::None).unwrap();
let pool = r2d2::Pool::new(manager).unwrap();
...
let conn = pconn.get().unwrap();
let request_query = format!("SELECT ... LIMIT 1;");
let request_rcon = conn.query(&request_query, &[]);
if request_rcon.is_err() {
...
}

I would expect the conn.query to return an error that I can catch when there is a connection issue but it doesn't. In both cases, it spins dumping the following to console:

 ERROR r2d2 > IO error: Connection refused (os error 111)
 ERROR r2d2 > IO error: Connection refused (os error 111)
 ERROR r2d2 > IO error: Connection refused (os error 111)
 ERROR r2d2 > IO error: Connection refused (os error 111)
 ERROR r2d2 > IO error: Connection refused (os error 111)

I would love a way where I can gracefully catch and handle this error, and not have the application hang.

add adapter for tokio-postgres

I use postgres with rust for backend but both diesel and rust-postgres are synchronous. I want to use tokio-postgres but there is no connection pool for it. I think it would be good if there was a adapter for it.

Please add information to the README

Coming to the repo it's completely undiscoverable what this library actually does. There is no information in the README at all nor is there even a description of the repo on GitHub.

Please add some information, atleast the basics would be appreciated.

Can't work with ffi ; i just want use cgo call the rust lib and hold the pool

error[E0277]: the type (dyn r2d2::HandleError<postgres::Error> + 'static) may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> src/lib.rs:81:5
|
81 | catch_unwind(|| {
| ^^^^^^^^^^^^ (dyn r2d2::HandleError<postgres::Error> + 'static) may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within *mut *mut r2d2::Pool<r2d2_postgres::PostgresConnectionManager>, the trait std::panic::RefUnwindSafe is not implemented for (dyn r2d2::HandleError<postgres::Error> + 'static)
= note: required because it appears within the type std::marker::PhantomData<(dyn r2d2::HandleError<postgres::Error> + 'static)>
= note: required because it appears within the type std::ptr::Unique<(dyn r2d2::HandleError<postgres::Error> + 'static)>
= note: required because it appears within the type std::boxed::Box<(dyn r2d2::HandleError<postgres::Error> + 'static)>
= note: required because it appears within the type r2d2::config::Config<postgres::Connection, postgres::Error>
= note: required because it appears within the type r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>
= note: required because it appears within the type std::marker::PhantomData<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>
= note: required because it appears within the type std::sync::Arc<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>
= note: required because it appears within the type r2d2::Pool<r2d2_postgres::PostgresConnectionManager>
= note: required because it appears within the type *mut r2d2::Pool<r2d2_postgres::PostgresConnectionManager>
= note: required because it appears within the type *mut *mut r2d2::Pool<r2d2_postgres::PostgresConnectionManager>
= note: required because of the requirements on the impl of std::panic::UnwindSafe for &*mut *mut r2d2::Pool<r2d2_postgres::PostgresConnectionManager>
= note: required because it appears within the type [closure@src/lib.rs:81:18: 90:6 c_sqlurl:&*const i8, c_size:&u16, out:&*mut *mut r2d2::Pool<r2d2_postgres::PostgresConnectionManager>]
note: required by catch_unwind
--> src/lib.rs:491:1
|
491| fn catch_unwind(f: F) -> CBoxResult where F: FnOnce() -> CBoxResult + UnwindSafe {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Is it useful prepare sql statement for PooledConnection๏ผŸ

loop {
    let conn = pool.get().unwrap();
    // if conn is reuse connection, call prepare_cached just return already statment,
    // if conn is new  prepare the statment and return;
    //  Is Right ?
    let stmp = conn.prepare_cached("sql").unwrap();
    stmt.query(&[]).unwrap();
}

Pool accuracy

New pool test after 41b268c
Test code same as
sfackler/r2d2-postgres#12

Expected: After idle_timeout pool redused to 2 connections
Reality: Pool reduced after max_lifetime to 3 connections and not renew used connections

Test query

SELECT a.pid, a.backend_start, a.query_start FROM pg_stat_activity a WHERE a.datid IS NOT NULL ORDER BY a.pid;

At begin

15490 / 2018-09-28 09:19:49.329870 / 2018-09-28 09:19:49.332444
15491 / 2018-09-28 09:19:49.330124 / 2018-09-28 09:19:52.336268
15492 / 2018-09-28 09:19:49.332135 / 2018-09-28 09:19:49.334726
15493 / 2018-09-28 09:19:49.333422 / 2018-09-28 09:19:49.334606

After around 1min (max_lifetime = Duration::from_secs(60))

15491 / 2018-09-28 09:19:49.330124 / 2018-09-28 09:20:19.360589
15620 / 2018-09-28 09:20:19.349820 / 
15621 / 2018-09-28 09:20:19.333852 / 

After 2min

15491 / 2018-09-28 09:19:49.330124 / 2018-09-28 09:21:21.400551
19526 / 2018-09-28 09:21:19.334243 / 
19527 / 2018-09-28 09:21:19.341293 / 

So, what happens if we use two connections instead of one?

    loop {
        println!("LOOP");
        let db1 = pool.get();
        println!("1/{} {:?}", db_max, db1.is_ok());

        let db2 = pool.get();
        println!("2/{} {:?}", db_max, db2.is_ok());

        std::thread::sleep(Duration::from_secs(1));
    }

After few minutes

435   / 2018-09-28 09:59:27.376183 / 
436   / 2018-09-28 09:59:27.377418 /
32146 / 2018-09-28 09:53:57.376039 / 2018-09-28 09:59:26.856081
32147 / 2018-09-28 09:53:57.376298 / 2018-09-28 09:59:26.856594

After more time used connections renew, but pool size not reduced

1447  / 2018-09-28 10:12:57.381760
1448  / 2018-09-28 10:12:57.381966
32146 / 2018-09-28 09:53:57.376039 / 2018-09-28 10:13:07.963099
32147 / 2018-09-28 09:53:57.376298 / 2018-09-28 10:13:07.963322

Same behavior on v0.8.2

pool running out (GetTimeout) on nightly

I'm getting some very strange behavior. My code works fine on a particular commit (pool used thousands of times, reclaims resources as connections fall out of scope). Then when I make the minimal changes necessary to upgrade to rust nightly (from 6-14 to 8-10) the (nearly) same code runs out of database connections quickly, even if I jack up the number of connections from my default 5 to any larger number, it will eventually consume them all.

The only changes I made to cause this to happen are:

  1. upgraded rust from 6-14 to 8-10 (also tried tonight's nightly)
  2. upgraded serde, serde_macros, serde_json (from 7 to 8)
  3. upgraded regex_macros (0.1.37 to 0.1.38)
  4. upgraded maud_macros (some commit to 0.9.2)
  5. upgraded bincode (0.5 to 0.6)
  6. upgraded handlebars (0.17 to 0.20)
  7. minor method renames related to (2) above
  8. a manual serialize/deserialize rewrite related to (2) above [that should not be in use]

Notice, no upgrades to r2d2, postgres, or r2d2-postgres

I've spent about 6 hours on this today. Tomorrow I'll see if a simple example exhibits the same behavior, then try bisecting rust-nightly versions.

how to drop a connection?

Hey, I was wondering when I would know a connection is dropped? Is it when it leaves scope? I just need to configure some things using one of the pooled connections and then drop it right away before launching the backend.

Connection example

What exactly is r2d2_foodb::FooConnectionManager in the example and is there a source code of it somewhere? I tried using something like this:

let config = r2d2::Config::default();
let manager = r2d2::ConnectionManager::new("postgres://postgres:postgres@localhost/test");
let error_handler = Box::new(r2d2::LoggingErrorHandler);
let pool = Arc::new(r2d2::Pool::new(config, manager, error_handler).unwrap());

but it throws an error

src/main.rs:125:16: 125:44 error: the value of the associated type `Error` (from the trait `r2d2::ConnectionManager`) must be specified [E0191]
src/main.rs:125     let manager = r2d2::ConnectionManager::new(DB_URI);
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:125:16: 125:44 error: the value of the associated type `Connection` (from the trait `r2d2::ConnectionManager`) must be specified [E0191]
src/main.rs:125     let manager = r2d2::ConnectionManager::new(DB_URI);
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:125:16: 125:44 error: no associated item named `new` found for type `r2d2::ConnectionManager` in the current scope
src/main.rs:125     let manager = r2d2::ConnectionManager::new(DB_URI);
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 3 previous errors

Are connections initialized synchronously?

In version 0.8.x, there's no longer an initialization_fail_fast option in the configuration for a Pool. Are connections always initialized synchronously now, or is there no way to achieve this behavior anymore?

Error: free(): invalid pointer

I'm using r2d2 in a (closed source) project for a customer, and it seems to try to incorrectly free a pointer.

stdout is: *** Error in `/home/vincent/coolerbot/release/bot': free(): invalid pointer: 0x00007f1e2c076c60 ***

Debian 3.16.59-1
rustc 1.32.0
r2d2 .8.3
pg-sys 0.4.6
diesel 1.4.1

postgres:

postgresql-10/jessie-pgdg,now 10.6-1.pgdg80+1 amd64 [installed]                                       
postgresql-client-10/jessie-pgdg,now 10.6-1.pgdg80+1 amd64 [installed,automatic]                      
postgresql-client-common/jessie-pgdg,now 199.pgdg80+1 all [installed,automatic]                       
postgresql-common/jessie-pgdg,now 199.pgdg80+1 all [installed,automatic]    

r2d2 pool is created with:

use diesel::pg::PgConnection;
use diesel::r2d2::ConnectionManager;
use r2d2::Pool;

#[derive(Clone)]
pub struct Connection {
    pub(crate) conn: Pool<ConnectionManager<PgConnection>>,
}

impl Connection {
    pub fn connect(url: &str) -> Result<Connection> {
        let conn = Pool::new(ConnectionManager::new(url))?;
        Ok(Connection { conn })
    }
}

fn main() {
    let conn = Connection::connect(&config.database_url).expect("Could not connect to database");
}

gdb backtrace:

#0  0x00007f1e34cdb067 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007f1e34cdc448 in __GI_abort () at abort.c:89
#2  0x00007f1e34d191b4 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7f1e34e0e210 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007f1e34d1e98e in malloc_printerr (action=1, str=0x7f1e34e0a326 "free(): invalid pointer", ptr=<optimized out>) at malloc.c:4996
#4  0x00007f1e34d1f696 in _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
#5  0x00007f1e3589c4a0 in ?? () from /usr/lib/x86_64-linux-gnu/libpq.so.5
#6  0x000055b45221eeb0 in r2d2::CustomizeConnection::on_release::hf8217cbd7c8ed8c5 ()
#7  0x000055b45221e2de in r2d2::drop_conns::h3df3ef3e77ab5c7f ()
#8  0x000055b45221ecf5 in r2d2::reap_connections::h84ed5f0047adfb7f ()
#9  0x000055b452281c31 in scheduled_thread_pool::Worker::run_job::h3b008cb21134a03b ()
#10 0x000055b452282311 in std::panicking::try::do_call::hef918f7ba5b2651f ()
#11 0x000055b4522a609a in __rust_maybe_catch_panic () at src/libpanic_unwind/lib.rs:102
#12 0x000055b4522819a9 in scheduled_thread_pool::Worker::run::h1861b2dabd2cd6ed ()
#13 0x000055b4522839f4 in std::sys_common::backtrace::__rust_begin_short_backtrace::h0ebd79a6a13e4f1f ()
#14 0x000055b4522a609a in __rust_maybe_catch_panic () at src/libpanic_unwind/lib.rs:102
#15 0x000055b45228362c in _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h8e8ed42246ded358 ()
#16 0x000055b452299cfe in call_once<(),()> () at /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b/src/liballoc/boxed.rs:683
#17 start_thread () at src/libstd/sys_common/thread.rs:24
#18 std::sys::unix::thread::Thread::new::thread_start::hca8e72c41fa9d291 () at src/libstd/sys/unix/thread.rs:90
#19 0x00007f1e3526f064 in start_thread (arg=0x7f1e31f23700) at pthread_create.c:309
#20 0x00007f1e34d8e62d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

fatal runtime error: stack overflow

When no servers are running, I get the following error:-

thread 'r2d2-worker-0' has overflowed its stack
fatal runtime error: stack overflow

This means that if I temporarily take the database down for maintenance or it goes down for some reason, my app crashes even when it could continue running using cached data.

Issue when impl Trait Key

Hi,

I have a issue when i use r2d2_postgres.

i create a struct named App, and it have a field pool, type is Arcr2d2::Pool, when i impl trait named
Key, i got a error. What is it mean?

src/main.rs:63:5: 63:53 error: the trait bound `r2d2_postgres::PostgresConnectionManager: r2d2::ManageConnection` is not satisfied [E0277]
src/main.rs:63     pool: Arc<r2d2::Pool<PostgresConnectionManager>>,
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:63:5: 63:53 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:63:5: 63:53 note: required by `r2d2::Pool`
src/main.rs:66:6: 66:9 error: the trait bound `r2d2_postgres::PostgresConnectionManager: r2d2::ManageConnection` is not satisfied [E0277]
src/main.rs:66 impl Key for App { type Value = App; }
                    ^~~
src/main.rs:66:6: 66:9 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `alloc::arc::ArcInner<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::marker::PhantomData<alloc::arc::ArcInner<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::ptr::Shared<alloc::arc::ArcInner<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::sync::Arc<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `r2d2::Pool<r2d2_postgres::PostgresConnectionManager>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `alloc::arc::ArcInner<r2d2::Pool<r2d2_postgres::PostgresConnectionManager>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::marker::PhantomData<alloc::arc::ArcInner<r2d2::Pool<r2d2_postgres::PostgresConnectionManager>>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::ptr::Shared<alloc::arc::ArcInner<r2d2::Pool<r2d2_postgres::PostgresConnectionManager>>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::sync::Arc<r2d2::Pool<r2d2_postgres::PostgresConnectionManager>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `App`
src/main.rs:66:6: 66:9 note: required by `iron::typemap::Key`
src/main.rs:89:5: 91:6 error: the trait bound `r2d2_postgres::PostgresConnectionManager: r2d2::ManageConnection` is not satisfied [E0277]
src/main.rs:89     pub fn conn(&self) -> Result<Connection, Error> {
src/main.rs:90         Ok(try!(self.pool.get()))
src/main.rs:91     }
src/main.rs:89:5: 91:6 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:89:5: 91:6 note: required by `r2d2::PooledConnection`

Returning connection from a pool without pool explicitly in scope

I'm not very experienced in rust yet, so I'm sorry for potential misunderstanding ;)

I ran into an issue where I'd like to abstract returning a connection from a pool into a function. Basically the original code in Iron request handler is:

fn front_page_handler(req: &mut Request) -> IronResult<Response> {
    let pool = req.get::<Read<Database>>().ok().expect("database component not initialised");
    let connection = pool.get().unwrap();
    ...

and I wanted to make the first two lines just let connection = get_pool_connection(req);. This however is not possible unless pool is returned along with the connection so it can live for the same time.

I was hoping this could be improved by storing an Rc<Pool> somewhere in the connection itself. Or maybe there are other ways to allow a function like this to exist:

fn get_pool_connection(req: &mut Request) -> PooledConnection<T> {
    let pool = req.get::<Read<Database>>().ok().expect("database component not initialised");
    pool.get().unwrap()
}

Related SO with the question and answer here: https://stackoverflow.com/questions/30252054/refactoring-messes-up-mutable-borrow-why

Better errors if connections can't be initiated

Right now all one gets is InitializationError(()) which gives very little information about what could have gone wrong, even if there is an informative error from the connection-opening function.

Error not returned until timeout occurs, no matter the error.

So I noticed if I use the wrong username, password, port, etc... then I will not get an error back until the connection timeout has occurred. Is the canonical way of dealing with this to use something like the postgres crate directly and make sure the credentials are correct before setting up a pool?

Inconsistent error reporting

The way errors are reported appears to be racey/inconsistent when a connection cannot be obtained from the pool. Sometimes you will just get Error(None), whilst other times you will get an actual error message from the connection manager. I assume this is because another thread happens to take the error message before the original thread gets to it.

I can see why there might be reasons to not want to synchronously establish the connection from the thread that could not find an available connection in the pool (eg. so that its request could be fullfilled sooner if another connection is returned to the pool more quickly) but I think when a connection cannot be established, it should behave as though it synchronously attempted to establish the new connection (guaranteeing a 1:1 relationship between failed requests and errors).

It would also be useful to distinguish failures due to hitting the "max_size" on the pool, from connection failures - at the moment you also (IIUC) get an Error(None) if the pool is maxed out.

Connection usage grows to maximum with even low concurrency

I have a connection pool configured like this:

let pool = r2d2::Pool::builder()
    .min_idle(Some(1))
    .idle_timeout(Some(Duration::from_secs(30)))
    .build(manager)?;

I expected this would approximately match my peak concurrent connection usage (ie. if I never use more than 3 concurrent connections, I would expect my connection usage to sit around 3).

However, in practice I've found that the connection pool starts around the expected size, but then after some time grows to whatever is the upper limit on connections.

I have nine different services deployed to my cluster, all using r2d2, all using the exact same connection pool configuration, and each one with 2-4 replicas. These services are divided into two types: those with background workers (ie. continually polling the database) and those without (pure request/response based).

All of the services with background workers eat up their maximum allocation of connections once they've been running for any non-trivial amount of time. I can also see that all of the connections have been recently active (within the last few seconds), so it's not a question of "leaking" zombie connections somehow.

These services with background workers only use a single thread for polling the database, so despite the fact that they perform constant DB access, they should never use more than 1 concurrent connection when idle.

Based on this, it appears that there's an issue with the way connections are given out from the pool - instead of giving out the "most recently used" connection for reuse, it must be giving out older or random connections from the pool, keeping all of them alive even when not needed.

Unwinding can result in connections with broken invariants being returned to the connection pool

Currently PooledConnection unconditionally returns the connection to the pool on drop. Since a panic could happen at any time, we can't assume that the connection will be in a good state if it's being dropped as the result of unwinding. r2d2 should either check thread::panicking before checking the connection back into the pool, or should have a T: UnwindSafe constraint on the connection.

MySQL support?

Using the r2d2-diesel crate,

    let db_manager = ConnectionManager::<MysqlConnection>::new(db_url);
    let db_pool = r2d2::Pool::new(db_config, db_manager).unwrap();

results in

error[E0277]: the trait bound `diesel::mysql::MysqlConnection: diesel::connection::Connection` is not satisfied
  --> src\main.rs:33:5
   |
33 |     db_pool: r2d2::Pool<ConnectionManager<MysqlConnection>>,
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::connection::Connection` is not implem
ented for `diesel::mysql::MysqlConnection`
   |
   = note: required because of the requirements on the impl of `r2d2::ManageConnection` for `r2d2_diesel::ConnectionManag
er<diesel::mysql::MysqlConnection>`
   = note: required by `r2d2::Pool`

error: aborting due to previous error

Obviously MysqlConnection is satisfied. Kinda confused.

Better Tutorial

Hi, I noticed the tutorial for this piece of Diesel rs is a bit lackluster. I am attempting to use r2d2 for its connection pool capabilities, but I have noticed it's kind of hard to get started with the example given.

use std::thread;

extern crate r2d2;
extern crate r2d2_foodb; // Where does this come from?

fn main() {
    let manager = r2d2_foodb::FooConnectionManager::new("localhost:1234"); // How does this get created?
    let pool = r2d2::Pool::builder()
        .max_size(15)
        .build(manager)
        .unwrap();

    for _ in 0..20 {
        let pool = pool.clone();
        thread::spawn(move || {
            let conn = pool.get().unwrap();
            // use the connection
            // it will be returned to the pool when it falls out of scope.
        })
    }
}

A cursory glance of this code still leaves me confused about how I may go about implementing this in my own system. For example, you import r2d2, but you use a connection manager for a separate r2d2 module, r2d2::foodb. After reading the source code for an example of how I can emulate this desired behavior, I have not been able to find what I am looking for. What is "foodb" and how does it get created as an external crate in this case?

Would you be willing to provide a more complete example of how this system works? It is still quite confusing in its current state.

the trait `diesel::Connection` is not implemented for `r2d2::PooledConnection<r2d2_diesel::ConnectionManager<diesel::pg::PgConnection>>`

Hello,

I have a connection pool, implemented like in writing a github webhook in rust pt 1,
code at this link. I'm not sure what I am doing wrong, but when I call

  let conn: db::DbConnection = db_pool.get().chain_err(|| "Could not connect to DB")?;

  let returned_user: User = diesel::insert(&user_data)
    .into(schema::users::table)
    .get_result(&conn)
    .chain_err(|| "Error inserting user")?;

I get the following error message:

error[E0277]: the trait bound `r2d2::PooledConnection<r2d2_diesel::ConnectionManager<diesel::pg::PgConnection>>: diesel::Connection` is not satisfied
  --> src/app/mod.rs:45:6
   |
45 |     .get_result(&conn)
   |      ^^^^^^^^^^ the trait `diesel::Connection` is not implemented for `r2d2::PooledConnection<r2d2_diesel::ConnectionManager<diesel::pg::PgConnection>>`

diesel::pg::PgConnection implements diesel::Connection. Is there any way to convert from a pooled connection to a regular connection? It doesn't look like it from the docs.

My workaround is to call the establish_connection method (from the same link as above), which returns a PgConnection. However, grabbing a pooled connection or a regular connection depending on whether we're inserting or querying seems really fishy.

Am I doing something wrong? Thank you!

Compiler gives error on r2d2::Pool<r2d2_mysql::MysqlConnectionManager>

Hi!
I'm trying to compile code:

struct Foo {
    pool: r2d2::Pool<r2d2_mysql::MysqlConnectionManager>,
} 

which gives me error

src/main.rs:65:5: 65:39 error: the trait bound `r2d2_mysql::MysqlConnectionManager: r2d2::ManageConnection` is not satisfied [E0277]
src/main.rs:65     pool: Pool<MysqlConnectionManager>,
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:65:5: 65:39 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:65:5: 65:39 note: required by `r2d2::Pool`

My Cargo.toml

[dependencies]
mysql = "*"
r2d2 = "*"
r2d2_mysql = "*"
rustc-serialize = "*"

If I try to use https://github.com/sfackler/r2d2-postgres and replace code with

struct Foo {
    pool: r2d2::Pool<r2d2_postgres::PostgresConnectionManager>,
} 

everything compiles.
I can't see real differences in this two cargos. Both have

impl r2d2::ManageConnection for PostgresConnectionManager {
impl r2d2::ManageConnection for MysqlConnectionManager {

I would appreciate any help. Thanks

Pool is never dropped, so all connections are left open

I'm having an issue with a long-running application that the connections made by r2d2 are not dropped after I drop the last reference to the pool. After digging through the code, I found that new_inner creates a second copy of the Arc here, which is then moved into the closure passed to read_connections. As far as I can tell, that closure is never dropped, which means the second reference to the Arc is never dropped, which in turn prevents the SharedPool the Arc wraps from being dropped. Since the SharedPool is never dropped, the workers are never stopped, and so the connections are all left open indefinitely.

With some debug statements inserted into r2d2 (patch below), I get the following output for my application:

new_inner::step s: 1, w: 0
new_inner::step s: 51, w: 0
pool worker starting
pool worker starting
pool worker starting
pool worker got job
...
pool worker got job
pool worker waiting
pool worker waiting
pool worker waiting
new_inner::step s: 1, w: 0
new_inner::step s: 2, w: 0
new pool (starts at s: 2, w: 0)
pool worker waiting
cloning pool (now s: 3, w: 0)
pool worker waiting
pool worker waiting
dropping instance of pool (was s: 3, w: 0)
cloning pool (now s: 3, w: 0)
cloning pool (now s: 4, w: 0)
dropping instance of pool (was s: 4, w: 0)
cloning pool (now s: 4, w: 0)
cloning pool (now s: 5, w: 0)
dropping instance of pool (was s: 5, w: 0)
cloning pool (now s: 5, w: 0)
cloning pool (now s: 6, w: 0)
dropping instance of pool (was s: 6, w: 0)
cloning pool (now s: 6, w: 0)
dropping instance of pool (was s: 6, w: 0)
dropping instance of pool (was s: 5, w: 0)
dropping instance of pool (was s: 4, w: 0)
dropping instance of pool (was s: 3, w: 0)
dropping instance of pool (was s: 2, w: 0)
all done -- sleeping...

Notice in particular how, by the time Pool::new returns, the Arc already has two strong references, and how, when my application drops its last reference (right before the "all done" line), there is still a leftover strong reference.

Debug patch:

diff --git a/src/lib.rs b/src/lib.rs
index a620344..6df3284 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -40,6 +40,7 @@
 //! ```
 #![warn(missing_docs)]
 #![doc(html_root_url="https://sfackler.github.io/r2d2/doc/v0.6.3")]
+#![feature(arc_counts)]

 #[macro_use]
 extern crate log;
@@ -175,10 +177,13 @@ struct SharedPool<M>
     thread_pool: ScheduledThreadPool,
 }

 impl<M> Drop for SharedPool<M> where M: ManageConnection
 {
     fn drop(&mut self) {
+        println!("dropping shared pool");
         self.thread_pool.clear();
+        println!("dropped shared pool");
     }
 }

@@ -258,14 +263,33 @@ fn reap_connections<M>(shared: &Arc<SharedPool<M>>)
 pub struct Pool<M: ManageConnection>(Arc<SharedPool<M>>);

 /// Returns a new `Pool` referencing the same state as `self`.
 impl<M> Clone for Pool<M> where M: ManageConnection
 {
     fn clone(&self) -> Pool<M> {
-        Pool(self.0.clone())
+        use std::sync;
+        let p = Pool(self.0.clone());
+        println!("cloning pool (now s: {}, w: {})",
+                 sync::Arc::strong_count(&self.0),
+                 sync::Arc::weak_count(&self.0));
+        p
     }
 }

+impl<M> Drop for Pool<M>
+    where M: ManageConnection
+{
+    fn drop(&mut self) {
+        use std::sync;
+        println!("dropping instance of pool (was s: {}, w: {})",
+                 sync::Arc::strong_count(&self.0),
+                 sync::Arc::weak_count(&self.0));
+    }
+}
+
+
 impl<M> fmt::Debug for Pool<M> where M: ManageConnection + fmt::Debug
 {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let inner = self.0.internals.lock().unwrap();
@@ -289,7 +314,15 @@ impl<M> Pool<M> where M: ManageConnection
     pub fn new(config: Config<M::Connection, M::Error>,
                manager: M)
                -> Result<Pool<M>, InitializationError> {
-        Pool::new_inner(config, manager, 30)
+        use std::sync;
+        let p = Pool::new_inner(config, manager, 30);
+        if p.is_ok() {
+            let p = p.as_ref().unwrap();
+            println!("new pool (starts at s: {}, w: {})",
+                     sync::Arc::strong_count(&p.0),
+                     sync::Arc::weak_count(&p.0));
+        }
+        p
     }

     // for testing
@@ -297,6 +330,7 @@ impl<M> Pool<M> where M: ManageConnection
                  manager: M,
                  reaper_rate: i64)
                  -> Result<Pool<M>, InitializationError> {
+        use std::sync;
         let internals = PoolInternals {
             conns: VecDeque::with_capacity(config.pool_size() as usize),
             num_conns: 0,
@@ -311,6 +345,10 @@ impl<M> Pool<M> where M: ManageConnection
             cond: Condvar::new(),
         });

+        println!("new_inner::step s: {}, w: {}",
+                 sync::Arc::strong_count(&shared),
+                 sync::Arc::weak_count(&shared));
+
         let initial_size = shared.config.min_idle().unwrap_or(shared.config.pool_size());
         {
             let mut inner = shared.internals.lock().unwrap();
@@ -320,6 +358,10 @@ impl<M> Pool<M> where M: ManageConnection
             drop(inner);
         }

+        println!("new_inner::step s: {}, w: {}",
+                 sync::Arc::strong_count(&shared),
+                 sync::Arc::weak_count(&shared));
+
         if shared.config.initialization_fail_fast() {
             let end = SteadyTime::now() + cvt(shared.config.connection_timeout());
             let mut internals = shared.internals.lock().unwrap();
@@ -336,12 +378,20 @@ impl<M> Pool<M> where M: ManageConnection
             }
         }

+        println!("new_inner::step s: {}, w: {}",
+                 sync::Arc::strong_count(&shared),
+                 sync::Arc::weak_count(&shared));
+
         if shared.config.max_lifetime().is_some() || shared.config.idle_timeout().is_some() {
             let s = shared.clone();
             shared.thread_pool
                   .run_at_fixed_rate(Duration::seconds(reaper_rate), move || reap_connections(&s));
         }

+        println!("new_inner::step s: {}, w: {}",
+                 sync::Arc::strong_count(&shared),
+                 sync::Arc::weak_count(&shared));
+
         Ok(Pool(shared))
     }

diff --git a/src/task.rs b/src/task.rs
index 51c5841..b99e9e1 100644
--- a/src/task.rs
+++ b/src/task.rs
@@ -75,8 +75,11 @@ pub struct ScheduledThreadPool {

 impl Drop for ScheduledThreadPool {
     fn drop(&mut self) {
+        println!("pool dropping");
         self.shared.inner.lock().unwrap().shutdown = true;
+        println!("pool notifying");
         self.shared.cvar.notify_all();
+        println!("pool notified");
     }
 }

@@ -165,12 +168,14 @@ impl Worker {
     }

     fn run(&mut self) {
+        println!("pool worker starting");
         loop {
             match self.get_job() {
                 Some(job) => self.run_job(job),
                 None => break,
             }
         }
+        println!("pool worker stopping");
     }

     fn get_job(&self) -> Option<Job> {
@@ -190,6 +195,8 @@ impl Worker {
                 Some(e) => Need::WaitTimeout(e.time - now),
             };

+            println!("pool worker waiting");
+
             inner = match need {
                 Need::Wait => self.shared.cvar.wait(inner).unwrap(),
                 Need::WaitTimeout(t) => {
@@ -206,6 +213,7 @@ impl Worker {
     }

     fn run_job(&self, job: Job) {
+        println!("pool worker got job");
         match job.type_ {
             JobType::Once(f) => f.invoke(()),
             JobType::FixedRate { mut f, rate } => {

Need panic safety

The pool should be able to deal with panics coming from the PoolManager and ErrorHandler methods.

The easiest solution would be to poison the pool like Mutex, but we could do better since the lock is never held during calls to user code. It's not clear if it's worth the effort though.

Keep a changelog

0.8.0 included significant breaking changes which have non-obvious migration paths. There is no documentation anywhere in this project of what changed, or how someone should migrate to the latest version. http://keepachangelog.com/ is a reasonable place to start if you're looking for a format to use.

Testing

It would be very nice if r2d2 would provide some mocking abilities to be able to test that database-accessing code will perform the things expected of it.

I'd like to be able to have an integration-style test where I init the connection, start a transaction, set some state for the DB, call the tests, and inspect the state of the DB afterwards, and finally, cancel the transaction. However, as my application (that uses Diesel + r2d2 + Rocket) uses r2d2 pool, achieving this isn't easy, since r2d2 manages all the connections, and having a transaction persist from before to after the test code doesn't work.

In the end, I ended up wrapping the r2d2 pool into a newtype, and having the implementation of the API of the newtype switched for a mock with #[cfg(test)]. Lately I'm embracing even more problems since I'm splitting my code into a library and a binary crate, and #[cfg(test)] applies only for the bottom crate being compiled.

If r2d2 had a "generic test connection manager" where instead of a pool, there would be only one prepared connection that is passed to it, writing tests like this would be a lot easier while keeping the same type interface. What do you think?

Builder doesn't work across different machines.

Perhaps this more of a upstream issue, but I have found that when using a binary on a different machine same OS and same packages are installed and I think even the hardware is the same, I get the error

Result::unwrap()` on an `Err` value: InitializationError(None)

I realize that this is error is thrown when the Pool::new get unwrapped, but I am actually blaming the builder object namely

    let config = r2d2::config::Builder::new().pool_size(20).build();
    println!("{:?}", config);

config will not print anything which is weird since Builder implements the debug trait. Any thoughts on how to resolve this?

Internal error occurred: Command "gcc.exe"

error: failed to run custom build command for miniz-sys v0.1.11
process didn't exit successfully: D:\Rust\Rd2dTest\target\debug\build\miniz-sys-d13c924666e24cd6\build-script-build (exit code: 101)
--- stdout
TARGET = Some("x86_64-pc-windows-gnu")
OPT_LEVEL = Some("0")
HOST = Some("x86_64-pc-windows-gnu")
CC_x86_64-pc-windows-gnu = None
CC_x86_64_pc_windows_gnu = None
HOST_CC = None
CC = None
CFLAGS_x86_64-pc-windows-gnu = None
CFLAGS_x86_64_pc_windows_gnu = None
HOST_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("true")
CARGO_CFG_TARGET_FEATURE = Some("fxsr,mmx,sse,sse2")
running: "gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-fno-omit-frame-pointer" "-m64" "-DMINIZ_NO_STDIO" "-DMINIZ_NO_ARCHIVE_APIS" "-DMINIZ_NO_ARCHIVE_WRITING_APIS" "-DMINIZ_NO_TIME" "-DMINIZ_NO_ZLIB_COMPATIBLE_NAMES" "-o" "D:\Rust\Rd2dTest\target\debug\build\miniz-sys-935e563594ae4ae2\out\miniz.o" "-c" "miniz.c"
cargo:warning=cc1.exe: sorry, unimplemented: 64-bit mode not compiled in
exit code: 1

--- stderr
thread 'main' panicked at '

Internal error occurred: Command "gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-fno-omit-frame-pointer" "-m64" "-DMINIZ_NO_STDIO" "-DMINIZ_NO_ARCHIVE_APIS" "-DMINIZ_NO_ARCHIVE_WRITING_APIS" "-DMINIZ_NO_TIME" "-DMINIZ_NO_ZLIB_COMPATIBLE_NAMES" "-o" "D:\Rust\Rd2dTest\target\debug\build\miniz-sys-935e563594ae4ae2\out\miniz.o" "-c" "miniz.c" with args "gcc.exe" did not execute successfully (status code exit code: 1).

', C:\Users\xiujie.zhu.cargo\registry\src\github.com-1ecc6299db9ec823\cc-1.0.35\src\lib.rs:2398:5
stack backtrace:
0: std::sys_common::backtrace::_print
at src\libstd\sys\windows\backtrace/mod.rs:95
at src\libstd\sys\windows\backtrace/mod.rs:82
at src\libstd\sys_common/backtrace.rs:71
1: std::panicking::default_hook::{{closure}}
at src\libstd\sys_common/backtrace.rs:59
at src\libstd/panicking.rs:197
2: std::panicking::default_hook
at src\libstd/panicking.rs:211
3: std::panicking::rust_panic_with_hook
at src\libstd/panicking.rs:474
4: std::panicking::continue_panic_fmt
at src\libstd/panicking.rs:381
5: std::panicking::begin_panic_fmt
at src\libstd/panicking.rs:336
6: cc::fail
at C:\Users\xiujie.zhu.cargo\registry\src\github.com-1ecc6299db9ec823\cc-1.0.35\src/lib.rs:2398
7: cc::Build::compile
at C:\Users\xiujie.zhu.cargo\registry\src\github.com-1ecc6299db9ec823\cc-1.0.35\src/lib.rs:951
8: build_script_build::main
at .\build.rs:23
9: std::rt::lang_start::{{closure}}
at /rustc/474e7a6486758ea6fc761893b1a49cd9076fb0ab\src\libstd/rt.rs:64
10: std::panicking::try::do_call
at src\libstd/rt.rs:49
at src\libstd/panicking.rs:293
11: _rust_maybe_catch_panic
at src\libpanic_unwind/lib.rs:87
12: std::rt::lang_start_internal
at src\libstd/panicking.rs:272
at src\libstd/panic.rs:388
at src\libstd/rt.rs:48
13: std::rt::lang_start
at /rustc/474e7a6486758ea6fc761893b1a49cd9076fb0ab\src\libstd/rt.rs:64
14: main
15: _tmainCRTStartup
16: mainCRTStartup
17: unit_addrs_search
18: unit_addrs_search

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.