petition_handler - MutakamwoyoCloud/MCloud GitHub Wiki

3.3.2.3.2 Módulo principal

Dependencias:

  • modulo Archiver.
  • fs de node

Clase de la parte back-end de la aplicación que se encargará de manejar las peticiones que se van a enviar al otro extremo y comprimirlas en paquetes.

Es el módulo principal del core, se encargará de manejar otros módulos al igual de atender a las peticiones que le pase nuestro servidor.

Constructor

Usado para instanciar un objeto manejador de peticiones. El parámetro package_size sirve para determinar el tamaño que va a tener en peticiones cada paquete comprimido. packa_size = 3 significa que cada paquete va a tener 3 peticiones.

qoldix y qnewidx son índices que nos sirven para saber el estado o el número de elementos de nuestra cola, qstorage será la memoria que guarde las que ya están listas en la cola preparadas mientras que petitions se encargará de tener guardadas en memoria las peticiones hasta que se alcance el número de paquetes deseado.

La relación del módulo principal con el módulo de almacenamiento es 1:1 por lo tanto sera también el encargado de crearlo y su control.

var PH = module.exports = function(package_size){
  Inicializadores:
                  Modelo
                  options
                  _qoldidx
                  _qnewidx 
                  _qstorage
                  _package_size
                  _petitionsObj
                  _petitionsNum 
};
Mecanica Principal del módulo
Crear Paquete

Función privada de la clase que se encarga de generar un paquete con el identificador (id) de la petición pasado por parámetros y la referencia a memoria (petitions) donde se encuentren nuestras peticiones almacenadas.

En su funcionamiento:

  • Crea un evento para inyectar código una vez de que el paquete se haya creado:
    • Comprueba posibles errores.
    • Crea un stream de escritura en el que escribirá dentro de los binarios.
    • Cerramos el stream.
    • Juntamos todas las peticiones para la compresión.
  • Insertamos en la colección fetch del modelo de datos nuestro package id.
//this function create a package and enqueue
function create_package(self, type){

  self.emitter.on("newPackage", function(id){
    var archive = archiver("tar",options); 

    //good practice to catch this error explicitly
    archive.on("error", function(err) { ... });

    // write stream
    var output = fs.createWriteStream( ... );

    // listen for all archive data to be written
    output.on("close", function() { ... });
    archive.pipe(output);
    self.enqueue(id);

    //Creating the package
    for (var i = 0, len = self._petitionsObj[type].length; i < len; i++){
      archive.append();
    }
    archive.finalize();
    self.reset(type);
  });
//Data model need to process the data required for fetch operation
self.data.do();  
}
Recepción de paquete

Función privada de la clase que se encarga de descomprimir todo lo que se encuentre en la ./pull/ y almacenar todos los JSON resultantes con los datos en la base de datos. Elimina todos los archivos descargados y descomprimidos cuando estos se han guardado en la base de datos.

En su funcionamiento:

  • Compramos el sistema de ficheros (carpeta pull).
  • Iteramos sobre los paquetes que encontremos dentro:
    • Descomprimíos cada paquete.
    • Leemos el contenido de cada paquete:
      • Según cada tipo de peticiones procesamos la información y la metemos al modelo.
    • Creamos un observador que se encarga de meter los ids tratados en una lista (remove) para poder realizar la operación flush una vez acabado el proceso.
function receive_package(self){
  //we check in pull folder if we have receive_packages to process
  fs.readdir(pull_folder, (err, files) => {

    //we iterate over the files checking the petition type
    files.forEach(file => { 

      //tar is in charge to access binary data and call the function to process
      tar.x({ ... }).then(_=> {
         fs.readdirSync(distFolder).forEach(function(file_decompress,index){ ... }
       }); 

      //Observer dedicated to check pull folder
      self.emitter.on("pulled", function(){ 
          fs.append(remove) //needed for flush
          self.data.do( ... ); //model operations
      });   
    });
  });

Funciones
Añadir petición

Esta función se encarga de almacenar una petición en memoria (data) y de crear un paquete en caso de que se haya alcanzado package_size, el paquete se encolará para respetar su orden y su tipo ya que al ser MCloud un sistema modular de conocimientos podremos tener distintos tipos de peticiones.

PH.prototype.add_petition= function(data){ ... };
Seccion Zona horaria

Conjunto privado de objetos y funciones de nuestro moduló principal, se encarga de planificar el horario de comunicación con el otro extremo del sistema y programar trabajos. Puede almacenar objetos time que sirven entre otras cosas para indicar tiempos de activación del sistema o de desactivación. La función de scheduleJob es un bloque en el que podemos escribir código que se ejecutará cuando llegue la hora y minutos indicados por el objeto time.

En MCloud gracias a esta interfaz podemos programar que se ejecuten operaciones de tipo push flush o pull a determinadas horas del día, ya que lo único que habría que hacer es llamar a las funciones que activan el módulo FTP.

object time
schedule.scheduleJob(time, function(){ ... });
search

Función a la cual pasamos un dato a buscar, comprueba en el modelo de datos su existencia y la retorna en caso de éxito. Nos da la opción de pasar un callback para ejecutar codigo junto con la búsqueda. Podemos interactuar con un conjunto de resultados. javascript

PH.prototype.search= function(callback, data, type){ ... }
reset

Función que se dedica a resetear la cola de peticiones dado un tipo. javascript

PH.prototype.reset = function(type){ ... }
searchOne

Función que recibe un dato a buscar, comprueba en el modelo de datos su existencia y la retorna en caso de éxito. Nos da la opción de pasar un callback para ejecutar codigo junto con la búsqueda. A diferencia de search en esta función podemos interactuar solo sobre 1 elemento y no un conjunto. javascript

PH.prototype.searchOne= function(callback, data, type){ ... }
Funciones relacionadas a la cola de peticiones
Size

Nos devuelve el número de elementos.

PH.prototype.size = function(){ ... };
enqueue

Encola el elemento data, normalmente un identificador para respetar el orden.

PH.prototype.enqueue = function(data) { ... };
dequeue

Quita un elemento de la cola y lo devuelve.

PH.prototype.dequeue = function(){ };
Ejemplo de uso

En el siguiente ejemplo vamos a crear un manejador que cree paquetes cada dos peticiones y después vamos a recorrer un bucle guardando "prueba" en cada petición.

var n = 2;
var petition_hander = new PH(n);

for (var i = 0, len = 10; i < len; i++){
  var prueba = "prueba";
  petition_hander.add_petition(prueba);

}

Resultado:

nPaquetes= len/n = 5 paquetes de dos peticiones, len%n = 0 por lo tanto se han empaquetado todas las peticiones.