Async Pool

Async Pool

Debido a que Uranium4Linux toma ventaja de la programación asíncrona es necesario una pool de tareas para que este pueda funcionar de forma eficiente.


El principal problema de las task es que no se puede saber el tiempo que va a tomar ejecutarlas por lo tanto necesitamos de algo que pueda comprobar si la task esta lista y, en caso de que lo este, guardar el resultado o aplicar alguna función.

Para conseguir esto he diseñado una estructura tal que:

pub struct AsyncPool<T> {
    request_pool: Vec<JoinHandle<T>>,
    items: usize,
    not_done_request: Vec<usize>,
    ordered_requests: HashMap<usize, T>
}

 

La idea original de la AsyncPool era que el orden en el que los resultados son devueltos a partir de task no estuviera garantizado. Es decir, si añado un vector con las tasks [1, 2, 3, 4] el vector con los resultados no debería tener los resultados de las tasks [1, 2, 3, 4] sino que podría estar [3, 1, 4, 2].


Para solucionar esto hice uso de lo que toda persona tiene que recurrir cuando necesita optimizar algo y tener fácil acceso a sus datos:

HASMAPS

AsyncPool está implementada de forma que siga todas las reglas de Rust por lo tanto aunque un poco tediosa es una implementación robusta. Debido a la forma en la que trabaja la Pool añadir el HashMap ha sido bastante fácil.

El funcionamiento es el siguiente:

AsyncPool antes de empezar a checkear si los resultados de nuestras tasks están completados tendrá que guardar el tamaño del vector donde se encuentran:

items = request_pool.len();

Ahora es cuando llega la parte donde nos guardamos los resultados. La Key de nuestro diccionario será la tarea que estamos checkeando y el valor será el resultado T que devuelva nuestra task.

ordered_requests.insert(index, result);

Una vez que todas las tasks se completen devolver un vector con los resultados ordenados será bastante sencillo. Solo tendremos que usar la lógica de un for loop tradicional:

for(int i = 0; i < items; i++)

(Lo he escrito en C con propósito de que sea mas fácil de entender) E ir insertando a nuestro vector los resultados:

let result_vector = Vec::new();
for i in 0..self.items{
   let value = self.ordered_requests.remove(&i).unwrap();
   done_requests.push(value);
}


El resto del código se puede encontrar en github en requester/asyc_pool.rs 

 

MORE DEVELOPMENT IS REQUIRED

Comentarios

Entradas populares de este blog

Curse, Murmur y 2

Crab Crab Crab, I'm gonna step on the Crab

Entrada Principal