mongodb / mongo-rust-driver

The official MongoDB Rust Driver
https://www.mongodb.com/docs/drivers/rust/current/
Apache License 2.0
1.44k stars 164 forks source link

Can't use the Tracing Instrument Method on the Collection Command Method in v3.0.0 #1150

Closed Kaizer303 closed 4 months ago

Kaizer303 commented 4 months ago

Versions/Environment

  1. Rust: 1.79.0
  2. OS: Windows 11 24H2 - WSL2 2.2.4
  3. Driver & Dependencies version:
    • mongodb@3.0.0
    • bson@2.11.0
    • tracing@1.40.0
    • tracing-subscriber@0.3.18
  4. MongoDB version: latest
  5. MongoDB topology: Standalone

Describe the bug

In driver version 3.0.0, I can't use the tracing instrument method (for working on OTEL reasons) on the collection command method, which worked in version 2.8.2.
For example:

// v2.8.2 is working
collection
    .find_one(doc! {}, None)
    .instrument(info_span!(
        "db.mongo.find_one",
        db.statement = &query.to_string(),
        db.system = "mongodb",
        db.operation = "find_one"
    ))
    .await
    .unwrap()

// v3.0.0 is not working
collection
    .find_one(doc! {})
    .instrument(info_span!(
        "db.mongo.find_one",
        db.statement = &query.to_string(),
        db.system = "mongodb",
        db.operation = "find_one"
    ))
    .await // <--- error here
    .unwrap()

error:

`mongodb::action::FindOne<'_, models::mongo::employment_type::EmploymentTypeResponse>` is not a future
the trait `futures::Future` is not implemented for `mongodb::action::FindOne<'_, models::mongo::employment_type::EmploymentTypeResponse>`, which is required by `tracing::instrument::Instrumented<mongodb::action::FindOne<'_, models::mongo::employment_type::EmploymentTypeResponse>>: std::future::IntoFuture`
required for `tracing::instrument::Instrumented<mongodb::action::FindOne<'_, models::mongo::employment_type::EmploymentTypeResponse>>` to implement `futures::Future`
required for `tracing::instrument::Instrumented<mongodb::action::FindOne<'_, models::mongo::employment_type::EmploymentTypeResponse>>` to implement `std::future::IntoFuture`

To Reproduce Steps to reproduce the behavior:

  1. First, downgrade to v2.8.2 and intrument method like example above.
  2. Then do this in v3.0.0.
  3. Bug occurs.

Thank you.

abr-egn commented 4 months ago

In 3.0, methods like find_one return a value that implements IntoFuture rather than the plain Future of 2.x. Because the compiler will automatically convert it when .await is called, in almost all cases this will be transparent. However, when working with other code that requires a Future (like tracing's instrument), an explicit into_future call is needed:

collection
    .find_one(doc! {})
    .into_future()  // <-- added
    .instrument(info_span!(
        "db.mongo.find_one",
        db.statement = &query.to_string(),
        db.system = "mongodb",
        db.operation = "find_one"
    ))
    .await
    .unwrap()

To bring that method into scope, you'll need to add a use std::future::IntoFuture; in the appropriate place as well.

Kaizer303 commented 4 months ago

Oh, Thank you very much.