rust - Returning a Transaction from a function for further use causes lifetime hell - Stack Overflow

I'm trying to write a function that returns a Transaction so that I may do some further async work

I'm trying to write a function that returns a Transaction so that I may do some further async work and either commit or rollback. However I'm facing an issue with the Transaction struct. The lifetime of it is such that as soon as the client or connection is dropped then I get errors related to the lifetime of the Transaction, which is understandable, but is there a way around this?

I've tried using tokio Mutex, Box and encapsulating in structs but nothing seems to work.

below is some pseudo code

#[async_trait]
trait myTrait {
  async fn start() -> Transaction {
         let mut client = self.get().await.unwrap(); // Get the client from the pool  
          let mut transaction = client.transaction().await.unwrap(); 
  
         // do some stuff with transaction
  
         transaction
  
  }
}

I'm using the following core libs

tokio = { version = "1.38", features = ["macros", "rt-multi-thread", "signal"] }
tokio-postgres = { version = "0.7", features = ["runtime", "array-impls"] }
tokio-postgres-rustls = "0.13"
bb8 = "0.9"
bb8-postgres = "0.9"
warp = "0.3"
async-trait = "0.1"

I'm trying to write a function that returns a Transaction so that I may do some further async work and either commit or rollback. However I'm facing an issue with the Transaction struct. The lifetime of it is such that as soon as the client or connection is dropped then I get errors related to the lifetime of the Transaction, which is understandable, but is there a way around this?

I've tried using tokio Mutex, Box and encapsulating in structs but nothing seems to work.

below is some pseudo code

#[async_trait]
trait myTrait {
  async fn start() -> Transaction {
         let mut client = self.get().await.unwrap(); // Get the client from the pool  
          let mut transaction = client.transaction().await.unwrap(); 
  
         // do some stuff with transaction
  
         transaction
  
  }
}

I'm using the following core libs

tokio = { version = "1.38", features = ["macros", "rt-multi-thread", "signal"] }
tokio-postgres = { version = "0.7", features = ["runtime", "array-impls"] }
tokio-postgres-rustls = "0.13"
bb8 = "0.9"
bb8-postgres = "0.9"
warp = "0.3"
async-trait = "0.1"
Share Improve this question edited Mar 20 at 15:19 Freddie Hands asked Mar 20 at 15:08 Freddie HandsFreddie Hands 93 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 2

Transaction holds a mutable reference to the Client. You can see it in its definition:

pub struct Transaction<'a> {
    client: &'a mut Client,
    savepoint: Option<Savepoint>,
    done: bool,
}

But in your function Client is a local variable. So essentially you are trying to return a reference to a previously deallocated stack frame, which Rust obviously rejects.

You can try solving this, by for example refactoring your function, so it takes a reference to the Client as an input parameter, and returning Transaction, that is bound to the lifetime of input client. Then the caller can control lifetime of the Client.

async fn prepare_transaction<'a>(client: &'a mut Client) -> Transaction<'a> {
    let mut transaction = client.transaction().await.unwrap(); 
  
    // do some stuff with transaction
  
    transaction
  
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744400862a4572379.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信