Untitled

El API de twitter no funciono asi que decidi usar la API de Spotify siguiendo el este tutorial

Analisis

Las querries REST se realizan de manera asincronica ya que no tengo control de cuanto tiempo vaya a tomar. Entonces uso async para esperar al Future. Le voy “pegando” como una piñata (internamente hace pull) hasta que me de un resultado (Result<T,E>)

async fn get_songs_by(query_artist:String, auth_token:&str) -> Result<APIResponse, String> {

	let url = format!(
        "<https://api.spotify.com/v1/search?q={query_artist}&type=track,artist>"
    );

    // chaining .await will yield our query result
    let result = client
                        .get(url)
                        .header(AUTHORIZATION, format!("Bearer {}", auth_token) )
                        .header(CONTENT_TYPE, "application/json")
                        .header(ACCEPT, "application/json")
                        .send()
                        .await;

	// No avanzo hasta esta linea hasta que tenga un resultado
	
	result.unwrap().json::<APIResponse>().await() // Devuelvo la query
}

<aside> 💡 Recordare que solo se puede usar .await() dentro de funciones async

Uso .await() para metodos bloqueantes

</aside>

Realizo varias queries las cuales las espero con un await porque no se cuanto tiempo me tome cada llamado.

Por cada query creo una tarea para ir intercalando entre tareas (desde un block_on de alguna funcion que la llame). Cuando se terminen todas las tareas, devuelvo el resultado.

async fn many_artist_info(artists:Vec<String>, auth_token: String) -> Vec<Result<APIResponse, String>>{

    let mut task_handles = vec![];

    // Creo un task por cada artista
    for artist in artists{
        let auth_token_clone = auth_token.clone(); 
        task_handles.push(task::spawn(async move {
            get_songs_by(artist.to_string(), &auth_token_clone).await
        }));
    }

    let mut responses = vec![];

    // Espero a que terminen todos los tasks
    for handle in task_handles {
        responses.push(
                        match  handle.await{
                            Ok(response) => response,
                            Err(_) => Err("Error".to_string()),
                        }
                    );
    }

    responses
}

Mi funcion main es sincronica, por ende debo esperar que termine todas las operaciones asincronicas usando block_on.

block_on se encarga de intercalar todas las tareas que se crean dentro de la funcion async