1

I have problems implement scylla-rust-driver on Rust Actix. I want just create simple CRUD with scyllaDb.

First i create struct for App Data

    struct AppState {
      scy_session: Session,
      app_name: String,
    }

Next i create Simple function

    #[get("/")] 
    async fn index(data: web::Data<AppState>) -> String {
       // I want to CRUD in this function with ScyllaDB
       let app_name = &data.app_name; // <- get app_name
       format!("Hello {}!", app_name) // <- response with app_name
    }

And finally main.rs is

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let session: Session = SessionBuilder::new()
        .known_node("localhost:9042")
        .user("username", "password")
        .build()
        .await
        .expect("Some error message");

    HttpServer::new(|| {
        App::new()
            .data(AppState {
                scy_session: session,
                app_name: String::from("Actix-web"),
            })
            .service(index)
    })
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

But show error :

error[E0277]: the trait bound `Session: Clone` is not satisfied in `[closure@src/main.rs:27:21: 34:6]`
  --> src/main.rs:27:5
   |
27 |       HttpServer::new(|| {
   |  _____^^^^^^^^^^^^^^^_-
   | |     |
   | |     within `[closure@src/main.rs:27:21: 34:6]`, the trait `Clone` is not implemented for `Session`

How actually implement scylla-rust-db on Actix web ? Thanks a lot

Pamungkas Jayuda
  • 1,194
  • 2
  • 13
  • 31
  • Not tested at all, but what if you add the `move` keyword to the closure? `HttpServer::new(move || {` – yolenoyer Nov 01 '21 at 08:34
  • still same error Mr. @yolenoyer - Thanks anyway ``` #[actix_web::main] | ^^^^^^^^^^^^^^^^^^ within `[closure@src/main.rs:27:21: 34:10]`, the trait `Clone` is not implemented for `Session` ... 27 | HttpServer::new(move||{ | _____________________- 28 | | App::new() 29 | | .data(AppState { 30 | | scy_session: session, ``` – Pamungkas Jayuda Nov 01 '21 at 08:38

1 Answers1

2

There is nothing special with Session, as seen here https://github.com/scylladb/scylla-rust-driver/blob/main/examples/parallel-prepared.rs

The solution is to wrap it in an Arc. We don't necessary need to do so ourselves as web::Data does this itself. Here is what I got.

use actix_web::{web, App, HttpResponse, HttpServer, Responder};

use scylla::{Session, SessionBuilder};

struct AppState {
    scy_session: Session,
    app_name: String,
}

/// Use the `Data<T>` extractor to access data in a handler.
async fn index(data: web::Data<AppState>) -> impl Responder {
    let app_name = &data.app_name; // <- get app_name
    HttpResponse::Ok().body(format!("Hello {}!", app_name))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let session: Session = SessionBuilder::new()
        .known_node("localhost:9042")
        .user("username", "passwor")
        .build()
        .await
        .expect("Some error message");
    let data = web::Data::new(AppState {
        scy_session: session,
        app_name: String::from("Actix-web"),
    });

    HttpServer::new(move || {
        App::new()
            .data(data.clone())
            .route("/", web::get().to(index))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

See also: https://stackoverflow.com/a/67772754/1418750

Njuguna Mureithi
  • 3,506
  • 1
  • 21
  • 41