Skip to content

feat: add pending request channel size configuration to ConnectionConfig #1328

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

dhvll
Copy link

@dhvll dhvll commented Apr 19, 2025

Make pending request channel size configurable

Changes

  1. Added [pending_request_channel_size] configuration option to [ConnectionConfig]
  2. Set a new default value of 2048 (up from 1024)
  3. Added comprehensive documentation explaining the configuration
  4. Updated connection creation to use the configurable channel size

Rationale

  • The previous fixed size of 1024 was too conservative for many workloads
  • cpp-driver uses 8192, but we chose 2048 as a more balanced default due to our per-connection queue architecture
  • This change provides flexibility while maintaining reasonable defaults

Usage

let session = SessionBuilder::new()
    .connection_config(
        ConnectionConfig::new()
            .with_pending_request_channel_size(4096)  // Customize as needed
    )
    .build()
    .await?;

Pre-review checklist

  • I have split my patch into logically separate commits.
  • All commit messages clearly explain what they change and why.
  • I added relevant tests for new features and bug fixes.
  • All commits compile, pass static checks and pass test.
  • PR description sums up the changes and reasons why they should be introduced.
  • I have provided docstrings for the public items that I want to introduce.
  • I have adjusted the documentation in ./docs/source/.
  • I added appropriate Fixes: annotations to PR description.

@github-actions github-actions bot added the semver-checks-breaking cargo-semver-checks reports that this PR introduces breaking API changes label Apr 19, 2025
Copy link

cargo semver-checks detected some API incompatibilities in this PR.
Checked commit: b295a21

See the following report for details:

cargo semver-checks output
./scripts/semver-checks.sh --baseline-rev a3faa6f259821aa6982054a576fcfdf43a6ce12c
+ cargo semver-checks -p scylla -p scylla-cql --baseline-rev a3faa6f259821aa6982054a576fcfdf43a6ce12c
     Cloning a3faa6f259821aa6982054a576fcfdf43a6ce12c
    Building scylla v1.1.0 (current)
error: running cargo-doc on crate 'scylla' failed with output:
-----
   Compiling libc v0.2.172
   Compiling proc-macro2 v1.0.95
   Compiling unicode-ident v1.0.18
   Compiling autocfg v1.4.0
   Compiling shlex v1.3.0
    Checking cfg-if v1.0.0
    Checking once_cell v1.21.3
   Compiling fs_extra v1.3.0
   Compiling dunce v1.0.5
   Compiling num-traits v0.2.19
   Compiling getrandom v0.3.2
    Checking pin-project-lite v0.2.16
   Compiling pkg-config v0.3.32
   Compiling vcpkg v0.2.15
   Compiling jobserver v0.1.33
   Compiling quote v1.0.40
   Compiling syn v2.0.100
   Compiling cc v1.2.19
    Checking zeroize v1.8.1
   Compiling aws-lc-rs v1.13.0
   Compiling slab v0.4.9
   Compiling fnv v1.0.7
   Compiling zerocopy v0.8.24
   Compiling ident_case v1.0.1
   Compiling version_check v0.9.5
   Compiling strsim v0.11.1
   Compiling cmake v0.1.54
   Compiling ahash v0.8.11
    Checking num-integer v0.1.46
    Checking socket2 v0.5.9
    Checking mio v1.0.3
    Checking futures-sink v0.3.31
   Compiling libm v0.2.11
    Checking bytes v1.10.1
    Checking futures-core v0.3.31
   Compiling aws-lc-sys v0.28.1
   Compiling openssl-sys v0.9.107
    Checking futures-channel v0.3.31
    Checking rand_core v0.9.3
   Compiling lock_api v0.4.12
   Compiling bigdecimal v0.4.8
   Compiling num-bigint v0.3.3
    Checking foreign-types-shared v0.1.1
    Checking untrusted v0.9.0
    Checking rustls-pki-types v1.11.0
    Checking static_assertions v1.1.0
   Compiling snap v1.1.1
   Compiling synstructure v0.13.1
   Compiling darling_core v0.20.11
   Compiling rustls v0.23.26
    Checking futures-task v0.3.31
    Checking futures-io v0.3.31
   Compiling parking_lot_core v0.9.10
   Compiling thiserror v2.0.12
    Checking memchr v2.7.4
    Checking powerfmt v0.2.0
   Compiling thiserror v1.0.69
   Compiling tokio-macros v2.5.0
   Compiling futures-macro v0.3.31
    Checking tokio v1.44.2
   Compiling zerofrom-derive v0.1.6
   Compiling darling_macro v0.20.11
   Compiling openssl v0.10.72
    Checking zerocopy v0.7.35
    Checking pin-utils v0.1.0
    Checking futures-util v0.3.31
    Checking zerofrom v0.1.6
   Compiling darling v0.20.11
   Compiling thiserror-impl v2.0.12
   Compiling thiserror-impl v1.0.69
   Compiling yoke-derive v0.7.5
   Compiling openssl-macros v0.1.1
    Checking deranged v0.4.0
    Checking ppv-lite86 v0.2.21
    Checking twox-hash v1.6.3
    Checking foreign-types v0.3.2
    Checking num-bigint v0.4.6
    Checking iana-time-zone v0.1.63
    Checking time-core v0.1.4
    Checking either v1.15.0
    Checking smallvec v1.15.0
    Checking log v0.4.27
    Checking scopeguard v1.2.0
    Checking num-conv v0.1.0
    Checking bitflags v2.9.0
    Checking allocator-api2 v0.2.21
    Checking stable_deref_trait v1.2.0
   Compiling tokio-openssl v0.6.5
    Checking subtle v2.6.1
    Checking hashbrown v0.14.5
    Checking yoke v0.7.5
    Checking time v0.3.41
    Checking itertools v0.14.0
    Checking chrono v0.4.40
    Checking rand_chacha v0.9.0
    Checking lz4_flex v0.11.3
    Checking futures-executor v0.3.31
   Compiling scylla-macros v1.1.0 (/home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla-macros)
   Compiling async-trait v0.1.88
   Compiling tracing-attributes v0.1.28
    Checking secrecy v0.8.0
    Checking uuid v1.16.0
    Checking tracing-core v0.1.33
    Checking byteorder v1.5.0
    Checking tracing v0.1.41
    Checking futures v0.3.31
    Checking histogram v0.11.3
    Checking rand v0.9.1
    Checking dashmap v5.5.3
    Checking scylla-cql v1.1.0 (/home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla-cql)
    Checking rand_pcg v0.9.0
    Checking arc-swap v1.7.1
    Checking rustls-webpki v0.103.1
    Checking tokio-rustls v0.26.2
 Documenting scylla v1.1.0 (/home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla)
�[38;5;9merror[E0432]: unresolved import `super::connection::ErrorReceiver`
 �[38;5;12m--> /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/network/connection_pool.rs:3:5
  �[38;5;12m|
�[38;5;12m3 �[38;5;12m|     ErrorReceiver, HostConnectionConfig, VerifiedKeyspaceName,
  �[38;5;12m|     �[38;5;9m^^^^^^^^^^^^^ �[38;5;9mno `ErrorReceiver` in `network::connection`

�[38;5;9merror[E0412]: cannot find type `ErrorReceiver` in this scope
   �[38;5;12m--> /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/network/connection.rs:464:24
    �[38;5;12m|
�[38;5;12m464 �[38;5;12m|     ) -> Result<(Self, ErrorReceiver), ConnectionError> {
    �[38;5;12m|                        �[38;5;9m^^^^^^^^^^^^^ �[38;5;9mnot found in this scope
    �[38;5;12m|
�[38;5;14mhelp: you might be missing a type parameter
    �[38;5;12m|
�[38;5;12m456 �[38;5;12m| impl�[38;5;10m<ErrorReceiver> Connection {
    �[38;5;12m|     �[38;5;10m+++++++++++++++

�[38;5;9merror[E0412]: cannot find type `ErrorReceiver` in this scope
    �[38;5;12m--> /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/network/connection.rs:1938:26
     �[38;5;12m|
�[38;5;12m1938 �[38;5;12m| ) -> Result<(Connection, ErrorReceiver), ConnectionError> {
     �[38;5;12m|                          �[38;5;9m^^^^^^^^^^^^^ �[38;5;9mnot found in this scope
     �[38;5;12m|
�[38;5;14mhelp: you might be missing a type parameter
     �[38;5;12m|
�[38;5;12m1934 �[38;5;12m| pub(crate) async fn open_connection�[38;5;10m<ErrorReceiver>(
     �[38;5;12m|                                    �[38;5;10m+++++++++++++++

�[38;5;9merror[E0412]: cannot find type `ErrorReceiver` in this scope
    �[38;5;12m--> /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/network/connection.rs:2057:26
     �[38;5;12m|
�[38;5;12m2057 �[38;5;12m| ) -> Result<(Connection, ErrorReceiver), ConnectionError> {
     �[38;5;12m|                          �[38;5;9m^^^^^^^^^^^^^ �[38;5;9mnot found in this scope
     �[38;5;12m|
�[38;5;14mhelp: you might be missing a type parameter
     �[38;5;12m|
�[38;5;12m2052 �[38;5;12m| pub(super) async fn open_connection_to_shard_aware_port�[38;5;10m<ErrorReceiver>(
     �[38;5;12m|                                                        �[38;5;10m+++++++++++++++

Some errors have detailed explanations: E0412, E0432.
For more information about an error, try `rustc --explain E0412`.
error: could not document `scylla`

-----

error: failed to build rustdoc for crate scylla v1.1.0
note: this is usually due to a compilation error in the crate,
      and is unlikely to be a bug in cargo-semver-checks
note: the following command can be used to reproduce the compilation error:
      cargo new --lib example &&
          cd example &&
          echo '[workspace]' >> Cargo.toml &&
          cargo add --path /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla --features bigdecimal-04,chrono-04,default,full-serialization,metrics,num-bigint-03,num-bigint-04,openssl-010,rustls-023,secrecy-08,time-03 &&
          cargo check

    Building scylla-cql v1.1.0 (current)
       Built [  12.185s] (current)
     Parsing scylla-cql v1.1.0 (current)
      Parsed [   0.039s] (current)
    Building scylla-cql v1.1.0 (baseline)
       Built [  10.977s] (baseline)
     Parsing scylla-cql v1.1.0 (baseline)
      Parsed [   0.038s] (baseline)
    Checking scylla-cql v1.1.0 -> v1.1.0 (no change)
     Checked [   0.665s] 148 checks: 148 pass, 0 skip
     Summary no semver update required
    Finished [  24.527s] scylla-cql
error: aborting due to failure to build rustdoc for crate scylla v1.1.0

Stack backtrace:
   0: anyhow::error::<impl anyhow::Error>::msg
   1: anyhow::__private::format_err
   2: cargo_semver_checks::data_generation::generate::run_cargo_doc
   3: cargo_semver_checks::data_generation::request::CrateDataRequest::resolve
   4: cargo_semver_checks::rustdoc_gen::generate_rustdoc
   5: <cargo_semver_checks::rustdoc_gen::RustdocFromProjectRoot as cargo_semver_checks::rustdoc_gen::RustdocGenerator>::load_rustdoc
   6: cargo_semver_checks::generate_crate_data
   7: cargo_semver_checks::Check::check_release
   8: cargo_semver_checks::exit_on_error
   9: cargo_semver_checks::main
  10: std::sys::backtrace::__rust_begin_short_backtrace
  11: main
make: *** [Makefile:64: semver-rev] Error 1

@wprzytula
Copy link
Collaborator

@dhvll CI is failing.
@Lorak-mmk Do you see value in adding such a config parameter?

@muzarski
Copy link
Contributor

@Lorak-mmk Do you see value in adding such a config parameter?

It's not that important feature, but cpp-rust-driver requires it. See the issue: #1313

@dhvll
Copy link
Author

dhvll commented Apr 29, 2025

I'll look into it.

Comment on lines +334 to +357

/// Set the size of the pending request channel for each connection.
///
/// # Arguments
///
/// * `size` - The maximum number of pending requests per connection.
///
/// # Notes
///
/// - This is different from cpp-driver's implementation, which uses a per-RequestProcessor queue.
/// - The default is 2048, a balanced value between performance and memory usage.
/// - Adjust based on your specific workload and system resources.
///
/// # Example
///
/// ```
/// let session = SessionBuilder::new()
/// .connection_config(
/// ConnectionConfig::new()
/// .with_pending_request_channel_size(4096)
/// )
/// .build()
/// .await?;
/// ```
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is worth describing what a "pending request" is. I think users may think that it is a request that was sent, but we did not yet receive response to (while in reality it is a request that has not yet been sent).

Comment on lines 481 to 484

// TODO: What should be the size of the channel?
let (sender, receiver) = mpsc::channel(1024);
let (sender, receiver) = mpsc::channel(config.pending_request_channel_size.unwrap_or(1024));
let (error_sender, error_receiver) = tokio::sync::oneshot::channel();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the TODO comment.
Also you are doing unwrap_or(1024), but you wrote in PR description that you changes the default to 2048 - it looks like a mistake.

Comment on lines 418 to 424
tablet_sender: None,

identity: SelfIdentity::default(),
pending_request_channel_size: Some(2048),
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that in connection you wrote .unwrap_or(1024) (which is a bug) tells me that this approach is too error-prone.

Why use an option here? I don't see anything optional - we need to create the channel, and it needs to have some size. Let's make it just usize.

Comment on lines 449 to 453

identity: SelfIdentity::default(),
pending_request_channel_size: Some(2048),
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-checks-breaking cargo-semver-checks reports that this PR introduces breaking API changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants