From 1edd17e07ef7dc6264175e4b229fef4304956428 Mon Sep 17 00:00:00 2001 From: Anatoly Ikorsky Date: Wed, 29 Dec 2021 14:42:40 +0300 Subject: [PATCH] docs: Add the "Crate Features" section --- Cargo.toml | 5 +++ README.md | 61 ++++++++++++++++++++------- src/buffer_pool.rs | 101 --------------------------------------------- src/conn/mod.rs | 16 +++---- src/lib.rs | 66 +++++++++++++++++++---------- 5 files changed, 103 insertions(+), 146 deletions(-) delete mode 100644 src/buffer_pool.rs diff --git a/Cargo.toml b/Cargo.toml index 269f44a..c4bf4c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,13 +31,18 @@ default = [ # It is necessary to choose one of `flate2` backends. "flate2/zlib", + # set of enabled-by-default mysql_common features "mysql_common/bigdecimal03", "mysql_common/rust_decimal", "mysql_common/time03", "mysql_common/uuid", "mysql_common/frunk", + + # use global buffer pool by default + "buffer-pool", ] rustls-tls = ["rustls", "webpki", "webpki-roots", "rustls-pemfile"] +buffer-pool = [] nightly = [] [dev-dependencies] diff --git a/README.md b/README.md index 83b6945..6024fc6 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,44 @@ assert_eq!(payments, selected_payments); println!("Yay!"); ``` +### Crate Features + +* crate's features: + + * **native-tls** (enabled by default) – specifies `native-tls` as the TLS backend + (see the [SSL Support](#ssl-support) section) + * **rustls-tls** (disabled by default) – specifies `rustls` as the TLS backend + (see the [SSL Support](#ssl-support) section) + * **buffer-pool** (enabled by default) – enables buffer pooling + (see the [Buffer Pool](#buffer-pool) section) + +* external features enabled by default: + + * for the `flate2` crate (please consult `flate2` crate documentation for available features): + + * **flate2/zlib** (necessary) – `zlib` backend is chosed by default. + + * for the `mysql_common` crate (please consult `mysql_common` crate documentation for available features): + + * **mysql_common/bigdecimal03** – the `bigdecimal03` is enabled by default + * **mysql_common/rust_decimal** – the `rust_decimal` is enabled by default + * **mysql_common/time03** – the `time03` is enabled by default + * **mysql_common/uuid** – the `uuid` is enabled by default + * **mysql_common/frunk** – the `frunk` is enabled by default + +Please note, that you'll need to reenable external features if you are using `no-default-features = true`: + +```toml +[dependencies] +# Lets say that we want to use the `rustls-tls` feature: +mysql = { version = "*", no-default-features = true, features = ["rustls-tls", "buffer-pool"] } +# Previous line disables default mysql features, +# so now we have to choose the flate2 backend (this is necessary), +# as well as the desired set of mysql_common features: +flate2 = { version = "*", no-default-features = true, features = ["zlib"] } +mysql_common = { version = "*", no-default-features = true, features = ["bigdecimal03", "time03", "uuid"]} +``` + ### API Documentation Please refer to the [crate docs]. @@ -637,15 +675,14 @@ that helps to avoid allocations for basic scenarios. You can control it's charac the following environment variables: * `RUST_MYSQL_BUFFER_POOL_CAP` (defaults to 128) – controls the pool capacity. Dropped buffer will - be immediately deallocated if the pool is full. - - **Note:** it might be the case, that you don't need the pooling (say you are using jemalloc). - It's possible to disable the pool by setting the `RUST_MYSQL_BUFFER_POOL_CAP` environment - variable to `0`. + be immediately deallocated if the pool is full. Set it to `0` to disable the pool at runtime. * `RUST_MYSQL_BUFFER_SIZE_CAP` (defaults to 4MiB) – controls the maximum capacity of a buffer stored in the pool. Capacity of a dropped buffer will be shrinked to this value when buffer - is returning to the pool. + is returned to the pool. + +To completely disable the pool (say you are using jemalloc) please remove the `buffer-pool` feature +from the set of default crate features (see the [Crate Features](#crate-features) section). #### `BinQuery` and `BatchQuery` traits. @@ -725,17 +762,9 @@ SSL support comes in two flavors: 1. Based on **native-tls** – this is the default option, that usually works without pitfalls (see the `native-tls` crate feature). 2. Based on **rustls** – TLS backend written in Rust. Please use the `rustls-tls` crate feature - to enable: - - ```toml - [dependencies] - mysql = { version = "*", no-default-features = true, features = ["rustls-tls"] } - # Please note, that the previous line disables default mysql features, - # so now we have to choose the flate2 backend (this is necessary): - flate2 = { version = "1.0", no-default-features = true, features = ["zlib"] } - ``` + to enable it (see the [Crate Features](#crate-features) section). - Please also note a few things about this backend: + Please also note a few things about **rustls**: * it will fail if you'll try to connect to the server by its IP address, hostname is required; * it, most likely, won't work on windows, at least with default server certs, generated by the diff --git a/src/buffer_pool.rs b/src/buffer_pool.rs deleted file mode 100644 index 8d9f2d0..0000000 --- a/src/buffer_pool.rs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2021 Anatoly Ikorsky -// -// Licensed under the Apache License, Version 2.0 -// or the MIT -// license , at your -// option. All files in the project carrying such notice may not be copied, -// modified, or distributed except according to those terms. - -use crossbeam::queue::ArrayQueue; - -use std::{mem::replace, ops::Deref, sync::Arc}; - -const DEFAULT_MYSQL_BUFFER_POOL_CAP: usize = 128; -const DEFAULT_MYSQL_BUFFER_SIZE_CAP: usize = 4 * 1024 * 1024; - -#[derive(Debug)] -struct Inner { - buffer_cap: usize, - pool: ArrayQueue>, -} - -impl Inner { - fn get(self: &Arc) -> PooledBuf { - let mut buf = self.pool.pop().unwrap_or_default(); - - // SAFETY: - // 1. OK – 0 is always within capacity - // 2. OK - nothing to initialize - unsafe { buf.set_len(0) } - - PooledBuf(buf, Some(self.clone())) - } - - fn put(&self, mut buf: Vec) { - buf.shrink_to(self.buffer_cap); - let _ = self.pool.push(buf); - } -} - -/// Smart pointer to a buffer pool. -#[derive(Debug, Clone)] -pub struct BufferPool(Option>); - -impl BufferPool { - pub fn new() -> Self { - let pool_cap = std::env::var("RUST_MYSQL_BUFFER_POOL_CAP") - .ok() - .and_then(|x| x.parse().ok()) - .unwrap_or(DEFAULT_MYSQL_BUFFER_POOL_CAP); - - let buffer_cap = std::env::var("RUST_MYSQL_BUFFER_SIZE_CAP") - .ok() - .and_then(|x| x.parse().ok()) - .unwrap_or(DEFAULT_MYSQL_BUFFER_SIZE_CAP); - - Self((pool_cap > 0).then(|| { - Arc::new(Inner { - buffer_cap, - pool: ArrayQueue::new(pool_cap), - }) - })) - } - - pub fn get(self: &Arc) -> PooledBuf { - match self.0 { - Some(ref inner) => inner.get(), - None => PooledBuf(Vec::new(), None), - } - } -} - -impl Default for BufferPool { - fn default() -> Self { - Self::new() - } -} - -#[derive(Debug)] -pub struct PooledBuf(Vec, Option>); - -impl AsMut> for PooledBuf { - fn as_mut(&mut self) -> &mut Vec { - &mut self.0 - } -} - -impl Deref for PooledBuf { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - self.0.deref() - } -} - -impl Drop for PooledBuf { - fn drop(&mut self) { - if let Some(ref inner) = self.1 { - inner.put(replace(&mut self.0, vec![])); - } - } -} diff --git a/src/conn/mod.rs b/src/conn/mod.rs index b62fdd3..f624fb0 100644 --- a/src/conn/mod.rs +++ b/src/conn/mod.rs @@ -41,7 +41,7 @@ use std::{ }; use crate::{ - buffer_pool::PooledBuf, + buffer_pool::{get_buffer, Buffer}, conn::{ local_infile::LocalInfile, pool::{Pool, PooledConn}, @@ -410,9 +410,9 @@ impl Conn { Ok(()) } - fn read_packet(&mut self) -> Result { + fn read_packet(&mut self) -> Result { loop { - let mut buffer = crate::BUFFER_POOL.get(); + let mut buffer = get_buffer(); if !self.stream_mut().next_packet(buffer.as_mut())? { return Err( io::Error::new(io::ErrorKind::BrokenPipe, "server disconnected").into(), @@ -441,7 +441,7 @@ impl Conn { } fn write_struct(&mut self, s: &T) -> Result<()> { - let mut buf = crate::BUFFER_POOL.get(); + let mut buf = get_buffer(); s.serialize(buf.as_mut()); self.write_packet(&mut &*buf) } @@ -462,7 +462,7 @@ impl Conn { fn handle_ok<'a, T: OkPacketKind>( &mut self, - buffer: &'a PooledBuf, + buffer: &'a Buffer, ) -> crate::Result> { let ok = ParseBuf(&**buffer) .parse::>(self.0.capability_flags)? @@ -652,7 +652,7 @@ impl Conn { Some(self.connect_attrs().clone()), ); - let mut buf = crate::BUFFER_POOL.get(); + let mut buf = get_buffer(); handshake_response.serialize(buf.as_mut()); self.write_packet(&mut &*buf) } @@ -771,7 +771,7 @@ impl Conn { } fn write_command_raw(&mut self, cmd: &T) -> Result<()> { - let mut buf = crate::BUFFER_POOL.get(); + let mut buf = get_buffer(); cmd.serialize(buf.as_mut()); self.reset_seq_id(); debug_assert!(buf.len() > 0); @@ -780,7 +780,7 @@ impl Conn { } fn write_command(&mut self, cmd: Command, data: &[u8]) -> Result<()> { - let mut buf = crate::BUFFER_POOL.get(); + let mut buf = get_buffer(); buf.as_mut().put_u8(cmd as u8); buf.as_mut().extend_from_slice(data); diff --git a/src/lib.rs b/src/lib.rs index fbc1946..9176b41 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,6 +103,44 @@ //! # }); //! ``` //! +//! ## Crate Features +//! +//! * crate's features: +//! +//! * **native-tls** (enabled by default) – specifies `native-tls` as the TLS backend +//! (see the [SSL Support](#ssl-support) section) +//! * **rustls-tls** (disabled by default) – specifies `rustls` as the TLS backend +//! (see the [SSL Support](#ssl-support) section) +//! * **buffer-pool** (enabled by default) – enables buffer pooling +//! (see the [Buffer Pool](#buffer-pool) section) +//! +//! * external features enabled by default: +//! +//! * for the `flate2` crate (please consult `flate2` crate documentation for available features): +//! +//! * **flate2/zlib** (necessary) – `zlib` backend is chosed by default. +//! +//! * for the `mysql_common` crate (please consult `mysql_common` crate documentation for available features): +//! +//! * **mysql_common/bigdecimal03** – the `bigdecimal03` is enabled by default +//! * **mysql_common/rust_decimal** – the `rust_decimal` is enabled by default +//! * **mysql_common/time03** – the `time03` is enabled by default +//! * **mysql_common/uuid** – the `uuid` is enabled by default +//! * **mysql_common/frunk** – the `frunk` is enabled by default +//! +//! Please note, that you'll need to reenable external features if you are using `no-default-features = true`: +//! +//! ```toml +//! [dependencies] +//! # Lets say that we want to use the `rustls-tls` feature: +//! mysql = { version = "*", no-default-features = true, features = ["rustls-tls", "buffer-pool"] } +//! # Previous line disables default mysql features, +//! # so now we have to choose the flate2 backend (this is necessary), +//! # as well as the desired set of mysql_common features: +//! flate2 = { version = "*", no-default-features = true, features = ["zlib"] } +//! mysql_common = { version = "*", no-default-features = true, features = ["bigdecimal03", "time03", "uuid"]} +//! ``` +//! //! ## API Documentation //! //! Please refer to the [crate docs]. @@ -684,15 +722,14 @@ //! the following environment variables: //! //! * `RUST_MYSQL_BUFFER_POOL_CAP` (defaults to 128) – controls the pool capacity. Dropped buffer will -//! be immediately deallocated if the pool is full. -//! -//! **Note:** it might be the case, that you don't need the pooling (say you are using jemalloc). -//! It's possible to disable the pool by setting the `RUST_MYSQL_BUFFER_POOL_CAP` environment -//! variable to `0`. +//! be immediately deallocated if the pool is full. Set it to `0` to disable the pool at runtime. //! //! * `RUST_MYSQL_BUFFER_SIZE_CAP` (defaults to 4MiB) – controls the maximum capacity of a buffer //! stored in the pool. Capacity of a dropped buffer will be shrinked to this value when buffer -//! is returning to the pool. +//! is returned to the pool. +//! +//! To completely disable the pool (say you are using jemalloc) please remove the `buffer-pool` feature +//! from the set of default crate features (see the [Crate Features](#crate-features) section). //! //! ### `BinQuery` and `BatchQuery` traits. //! @@ -776,17 +813,9 @@ //! 1. Based on **native-tls** – this is the default option, that usually works without pitfalls //! (see the `native-tls` crate feature). //! 2. Based on **rustls** – TLS backend written in Rust. Please use the `rustls-tls` crate feature -//! to enable: -//! -//! ```toml -//! [dependencies] -//! mysql = { version = "*", no-default-features = true, features = ["rustls-tls"] } -//! # Please note, that the previous line disables default mysql features, -//! # so now we have to choose the flate2 backend (this is necessary): -//! flate2 = { version = "1.0", no-default-features = true, features = ["zlib"] } -//! ``` +//! to enable it (see the [Crate Features](#crate-features) section). //! -//! Please also note a few things about this backend: +//! Please also note a few things about **rustls**: //! //! * it will fail if you'll try to connect to the server by its IP address, hostname is required; //! * it, most likely, won't work on windows, at least with default server certs, generated by the @@ -801,8 +830,6 @@ #[cfg(feature = "nightly")] extern crate test; -use std::sync::Arc; - use mysql_common as myc; pub extern crate serde; pub extern crate serde_json; @@ -894,9 +921,6 @@ pub mod prelude { #[doc(inline)] pub use crate::myc::params; -static BUFFER_POOL: once_cell::sync::Lazy> = - once_cell::sync::Lazy::new(|| Default::default()); - #[doc(hidden)] #[macro_export] macro_rules! def_database_url {