1 year ago
#372931
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