blackbeam / mysql_async

Asyncronous Rust Mysql driver based on Tokio.
Apache License 2.0
376 stars 114 forks source link

methods from mysql into mysql_async differ #102

Open nbari opened 4 years ago

nbari commented 4 years ago

Hi, I am trying to use mysql_async from existing code using mysql (https://docs.rs/mysql) but notice that some methods are missing or not the same, for example, the ip_or_hostname

/// Address of mysql server (defaults to `127.0.0.1`). Hostnames should also work.
    pub fn ip_or_hostname<T: Into<String>>(&mut self, ip_or_hostname: T) -> &mut Self {
        self.ip_or_hostname = ip_or_hostname.into();
        self
    }

From https://docs.rs/mysql/18.0.0/src/mysql/conn/opts.rs.html#471-477

/// Address of mysql server (defaults to `127.0.0.1`). Hostnames should also work.
///
/// **Note:** IPv6 addresses must be given in square brackets, e.g. `[::1]`.
pub fn ip_or_hostname<T: Into<String>>(mut self, ip_or_hostname: Option<T>) -> Self {
    let new = ip_or_hostname.map(Into::into).unwrap_or("127.0.0.1".into());
    self.opts.0.ip_or_hostname = url::Host::parse(&new)
        .map(|host| host.to_owned())
        .unwrap_or_else(|_| url::Host::Domain(new.to_owned()));
    self
}

When creating the pool, how in mysql_assync use https://docs.rs/mysql/18.0.0/mysql/struct.Pool.html#method.new_manual so that min and max could be used?

Could it be possible to keep the methods with the same signatures and options?

blackbeam commented 4 years ago

Notice that some methods are missing or not the same, for example, the ip_or_hostname.

Yeah, crates are developed independently and may support different set of features at some point in time. Usually I'm trying to keep them up with each other.

The change, mentioned by you, is relatively new in the mysql create and I'm planning to apply it also to mysql_async in the nearest future.

When creating the pool, how in mysql_async use new_manual...

Please use OptsBuilder::pool_options.

Could it be possible to keep the methods with the same signatures and options?

I think it's possible, at least for inhabitants of the opts module.

nbari commented 4 years ago

Hi @blackbeam , thanks , regarding the OptsBuilder::pool_options. I am testing with something like this:

opts.pool_options(mysql_async::PoolOptions::with_constraints(
      mysql_async::PoolConstraints::new(10, 50).unwrap(),
 ));
let pool = mysql_async::Pool::new(opts);
let conn = pool.get_conn().await.unwrap_or_else(|e| {
    eprintln!("Could not connect to MySQL: {}", e);
    process::exit(1);
});
println!("{:#?}", conn);

I can connect and do some queries but I notice that there is only 1 connection instead of 10 as the minimum defined for the pool, therefore wondering if something else is required to start the pool with the defined options.

Thanks in advance.

blackbeam commented 4 years ago

I can connect and do some queries but I notice that there is only 1 connection instead of 10 as the minimum defined for the pool, therefore wondering if something else is required to start the pool with the defined options.

Pool behaviour in mysql_async differs in that it won't fill itself to min boundary on creation. There reason behind this is that I wanted to keep pool constructors synchronous.

nbari commented 4 years ago

How could then I create the pool and then pass it as a reference, or it is going to fill up after used 10 times for example?

I was thinking of having a normal fn main() in where I could declare the pool and then have or start all the logging calling an async method but I don't know if this is possible with tokio I mean something like:

fn main() {
// create pool etc
}

#[tokio::main]
fn start {
}
blackbeam commented 4 years ago

How could then I create the pool and then pass it as a reference, or it is going to fill up after used 10 times for example?

Pool instance is simply an Arc reference under the hood. Yeah it'll fill up lazily from zero connections to min as soon as you acquire min simultaneous connections.

I was thinking of having a normal fn main() in where I could declare the pool and then have or start all the logging calling an async method but I don't know if this is possible with tokio.

Since constructors are synchronous they adds no restrictions on how to instantiate a pool (within synchronous or asynchronous function). Also, since pool is an Arc, each clone of a pool instance will actually be the same instance, so you can create one and giveaway its clones anywhere you want.

nbari commented 4 years ago

Hi, while moving code from mysql to mysql_async again hit the issue with ip_or_hostname any change that in the next release these changes could be unified?

I mainly use https://crates.io/crates/dsn to parse the DSN (returns options), so is very handy for example in mysql to use something like:

let mut opts = mysql::OptsBuilder::new();
opts.user(dsn.username);
opts.pass(dsn.password.clone());
opts.ip_or_hostname(dsn.host);
if let Some(port) = dsn.port {
    opts.tcp_port(port);
}
opts.socket(dsn.socket);
opts.db_name(dsn.database);

// mysql ssl options
let mut ssl_opts = mysql::SslOpts::default();
if let Some(tls) = dsn.params.get("tls") {
    if *tls == "skip-verify" {
        ssl_opts.set_danger_accept_invalid_certs(true);
    }
}
opts.ssl_opts(ssl_opts);