如何修复“等待在这里进行”,``mut metadata_pool''可能以后使用。

发布于 2025-01-19 07:27:12 字数 3139 浏览 3 评论 0原文

该代码在Rocket板条的HTTP处理程序上不起作用。

错误:

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)

功能

 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);
}

The code doesn't work on http handler of rocket crate.

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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文