1 year ago

#372931

test-img

Eren A. Akyol

How to solve the problem? await occurs here, with `mut metadata_pool` maybe used later

The code doesn't work on http handler of rocket crate. I don't understand what is the problem here. Can anyone help me?

Error:

error: future cannot be sent between threads safely
   --> src/main.rs:27:1
    |
27  | #[get("/eth/rarity/<contract_address>")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `std::marker::Send` is not implemented for `dyn StdError`
note: future is not `Send` as this value is used across an await
   --> src/eth.rs:61:14
    |
52  |           let mut metadata_pool: Vec<
    |               ----------------- has type `Vec<Vec<Result<TokenMetadata, Box<dyn StdError>>>>` which is not `Send`
...
61  |               )
    |  ______________^
62  | |             .await;
    | |__________________^ await occurs here, with `mut metadata_pool` maybe used later
...
148 |       }
    |       - `mut metadata_pool` is later dropped here
    = note: required for the cast to the object type `dyn futures::Future<Output = Outcome<rocket::Response<'__r>, Status, rocket::Data<'__r>>> + std::marker::Send`
    = note: this error originates in the attribute macro `get` (in Nightly builds, run with -Z macro-backtrace for more info)

function

 pub async fn rarity_sort(
        contract: &Contract<WebSocket>,
    ) -> DefaultResult<(RarityRank, AttributesRarity)> {
        let mut tokens: Vec<TokenMetadata> = Vec::new();
        let total_supply = contract_total_supply(&contract).await.unwrap_or(10_000);

        let mut metadata_pool: Vec<
            Vec<Result<TokenMetadata, _>>,
        > = Vec::new();
        let ids = (0..total_supply).collect::<Vec<_>>();
        for id_pool in ids.chunks(20) {
            let results = join_all(
                id_pool
                    .into_iter()
                    .map(|i| token_metadata(&contract, i + 1)),
            )
            .await;
            metadata_pool.push(results);
        }

        let mut attributes: HashMap<String, HashMap<String, i64>> = HashMap::new();
        for metadatas in metadata_pool {
            for metadata in metadatas {
                let metadata = metadata.unwrap();
                tokens.push(metadata.clone());

main.rs

#[get("/eth/rarity/<contract_address>")]
async fn index(contract_address: String) -> String {
    let api_key = env::var("INFURA_API_KEY").unwrap();

    let source =
        WebSocket::new(format!("wss://mainnet.infura.io/ws/v3/{}", api_key).as_str()).await;
    let web3s = Web3::new(source.unwrap());

    let address: H160 = contract_address.parse().unwrap();
    let token_contract =
        Contract::from_json(web3s.eth(), address, include_bytes!("erc721-abi.json")).unwrap();

    let result = eth::eth::rarity_sort(&token_contract).await;
    let (rank, attributes) = result.unwrap();

    return format!("{:?} {:?}", rank, attributes);
}

rust

rocket

0 Answers

Your Answer

Accepted video resources