job* crearJob(char* argv[]){ job* nuevo = (job*)malloc(sizeof(job)); nuevo->id = 0; nuevo->socketFd = 0; if( access( argv[2], F_OK ) == -1 ) { finalizarJob(FALLO_INGRESO); } if( access( argv[3], F_OK ) == -1 ) { finalizarJob(FALLO_INGRESO); } nuevo->rutaTransformador.cadena = string_duplicate(argv[2]); nuevo->rutaTransformador.longitud = string_length(nuevo->rutaTransformador.cadena); nuevo->rutaReductor.cadena = string_duplicate(argv[3]); nuevo->rutaReductor.longitud = string_length(nuevo->rutaReductor.cadena); nuevo->rutaDatos.cadena= string_duplicate(argv[4]); nuevo->rutaDatos.longitud = string_length(nuevo->rutaDatos.cadena); nuevo->rutaResultado.cadena = string_duplicate(argv[5]); nuevo->rutaResultado.longitud = string_length(nuevo->rutaResultado.cadena); estadisticas = crearEstadisticasProceso(); return nuevo; }
void planificar(job* job){ pthread_mutex_lock(&mutexJobs); infoNodo* worker = malloc(sizeof(infoNodo)); pthread_mutex_unlock(&mutexJobs); t_list* listaNodos = list_create(); int nodos,bloques; informacionArchivoFsYama* infoArchivo = recibirInfoArchivo(job);//RECIBE BLOQUES Y TAMAÑO DE FS SOBRE EL ARCHIVO DEL JOB llenarListaNodos(listaNodos,infoArchivo); if(list_is_empty(listaNodos)){ finalizarJob(job,TRANSFORMACION,FALLO_INGRESO); } calcularDisponibilidadWorkers(listaNodos); worker = posicionarClock(listaNodos);//POSICIONA EL CLOCK EN EL WORKER DE MAYOR DISPONIBILIDAD calcularNodosYBloques(infoArchivo,&nodos,&bloques); bool** matrix = llenarMatrizNodosBloques(infoArchivo,nodos,bloques); respuestaSolicitudTransformacion* respuestaMaster = moverClock(worker, listaNodos, matrix, infoArchivo->informacionBloques,job->id); empaquetar(job->socketFd,mensajeRespuestaTransformacion,0,respuestaMaster); actualizarCargasNodos(job->id,TRANSFORMACION); planificarReduccionesLocales(job,matrix,respuestaMaster,nodos,bloques); enviarReduccionGlobalAMaster(job); actualizarCargasNodos(job->id,RED_GLOBAL); mostrarTablaDeEstados(); esperarRespuestaReduccionDeMaster(job); realizarAlmacenamientoFinal(job); free(infoArchivo); free(respuestaMaster); free(listaNodos); free(worker); finalizarJob(job,4,OK); }
void esperarInstruccionesDeYama() { respuesta instruccionesYama; respuestaSolicitudTransformacion* infoTransformacion ; nodosRedLocal* infoRedLocal; respuestaReduccionGlobal* infoRedGlobal; workerDesdeYama* worker; respuestaAlmacenamiento* almacenamiento; int fallo; while (1) { instruccionesYama = desempaquetar(socketYama); switch (instruccionesYama.idMensaje) { case mensajeRespuestaTransformacion: infoTransformacion = (respuestaSolicitudTransformacion*)instruccionesYama.envio; log_trace(loggerMaster, "Recibo Transformacion de YAMA."); inicializarTiemposTransformacion(infoTransformacion); crearHilosConexionTransformacion(infoTransformacion); break; case mensajeRespuestaRedLocal: infoRedLocal = (nodosRedLocal*)instruccionesYama.envio; log_trace(loggerMaster, "Recibo Reduccion Local en nodo %d de YAMA.",infoRedLocal->numeroNodo); crearHilosConexionRedLocal(infoRedLocal); break; case mensajeDesconexion: log_error(loggerMaster, "Error inesperado al recibir instrucciones de YAMA."); exit(1); break; case mensajeReplanificacion: worker= instruccionesYama.envio; log_trace(loggerMaster, "Recibo Replanificacion para bloque en nodo %d de YAMA.",worker->numeroWorker); crearHilosPorBloqueTransformacion(worker); break; case mensajeFinJob: fallo = *(int*)instruccionesYama.envio; log_trace(loggerMaster, "Finaliza job."); finalizarJob(fallo); break; case mensajeRespuestaRedGlobal: infoRedGlobal = (respuestaReduccionGlobal*)instruccionesYama.envio; log_trace(loggerMaster, "Recibo Reduccion Global en nodo %d de YAMA.",infoRedGlobal->numero); enviarAEncargadoRedGlobal(infoRedGlobal); break; case mensajeRespuestaAlmacenamiento: almacenamiento = (respuestaAlmacenamiento*)instruccionesYama.envio; log_trace(loggerMaster, "Recibo Almacenamiento Final en nodo %d de YAMA.",almacenamiento->nodo); enviarAlmacenamientoFinal(almacenamiento); break; } } }
int main(int argc, char *argv[]) { if(argc!=2)//Validar que reciba archivo de configuracion por parametro { fprintf(stderr,"ERROR: el job debe recibir por parametro el path del archivo de configuracion \n"); exit(1); } pthread_mutex_init(&semaforoMarta,NULL); Job *job = levantarArchivoConfiguracion(argv[1]); iniciarYEstablecerRutaArchivoLog(job->path_log); logDebug("Comenzando el job..."); //Conectarse a marta SocketConecta *conectarAMarta = newSocketConecta(job->ip_marta, job->puerto_marta); conectarAServidor(conectarAMarta); if(estaConectado(conectarAMarta)) { //Muestro por pantalla la conexion a marta logConexionMarta("Se ha conectado correctamente a Marta con IP: %s y PUERTO: %s \n",job->ip_marta, job->puerto_marta); }else {logDebug("No se pudo conectar a Marta");exit(1);} enviarMensaje(conectarAMarta,job->combiner,2);/*envio si soporto combiner(string) si o no*/ logCabeceraEnvia("Soporte de combiner"); //Envio archivos int i=0; while(job->archivos[i]!=NULL) { //Envio la longitud del string del archivo int tamanio = strlen(job->archivos[i]); enviarMensaje(conectarAMarta,&tamanio,sizeof(int)); logCabeceraEnvia("Longitud de path de archivo"); //Envio el archivo actual enviarMensaje(conectarAMarta,job->archivos[i],strlen(job->archivos[i])); logCabeceraEnvia("Envio de archivo"); i++; } //Aviso a marta que termine de mandar los archivos int finArch =12; enviarMensaje(conectarAMarta,&finArch,sizeof(int)); enviarMensaje(conectarAMarta,"Fin archivos",12); logCabeceraEnvia("Finalizacion de envio de archivos"); //Recibo un 0 si no termina, recibo 1 cuando es el fin del job (YA NO ES ASI) //int fin = 0; int cantidadHilos=0; t_list *listaHilos = list_create(); while(1) { char *rutina=malloc(4); //Recibo que rutina se va a ejecutar (map o red) con '\0' al final, si recibo "fin" termino el job recibirYChequearConexion(conectarAMarta,rutina,4); logCabeceraRecibe("Rutina a ejecutar"); // SOLO ACA PUEDE TERMINAR EL JOB, RECIBO UNA RUTINA A EJECUTAR QUE SEA "fin" if(strcmp(rutina,"fin")==0) { free(rutina); finalizarJob(cantidadHilos,listaHilos,conectarAMarta,job,i); return EXIT_SUCCESS; } //Recibo ip del nodo al que le comunico int tamIp=0; recibirYChequearConexion(conectarAMarta,&tamIp,sizeof(int)); char *ipNodo=malloc(tamIp); recibirYChequearConexion(conectarAMarta,ipNodo,tamIp); logCabeceraRecibe("Ip del nodo"); //Recibo puerto del nodo int tamPuerto=0; recibirYChequearConexion(conectarAMarta,&tamPuerto,sizeof(int)); char *puertoNodo=malloc(tamPuerto); recibirYChequearConexion(conectarAMarta,puertoNodo,tamPuerto); logCabeceraRecibe("Puerto del nodo"); //Recibo donde se guarda el resultado de la operacion en espacio temporal int tamResul = 0; recibirYChequearConexion(conectarAMarta,&tamResul,sizeof(int)); char *resulOperacion=malloc(tamResul); recibirYChequearConexion(conectarAMarta,resulOperacion,tamResul); logCabeceraRecibe("Archivo de resultado de la operacion"); //Segun que rutina sea creo un hilo para enviar la rutina al nodo if(strcmp(rutina,"map")==0) { free(rutina); //Recibo bloque e id de la operacion int bloque = 0; int idMap = 0; recibirYChequearConexion(conectarAMarta,&bloque,sizeof(int)); logCabeceraRecibe("Bloque del nodo"); recibirYChequearConexion(conectarAMarta,&idMap,sizeof(int)); logCabeceraRecibe("Id de operacion map"); //Cargo la estructura hiloM t_hiloMapper *hiloM= malloc(sizeof(t_hiloMapper)); hiloM->ipNodo=strdup(ipNodo); hiloM->puertoNodo=strdup(puertoNodo); hiloM->mapper=strdup(job->mapper); hiloM->conectarAMarta=conectarAMarta; hiloM->bloque=bloque; hiloM->resulMap=strdup(resulOperacion); hiloM->idMap=idMap; pthread_t hiloMapper; pthread_create(&hiloMapper,NULL,enviarMapperYObtenerResultado,hiloM); list_add(listaHilos,&hiloMapper); cantidadHilos++; free(resulOperacion); //Muestro que se creo un hilo logCreacionHiloMapper("Se creo un hilo mapper con parametros: Ip_Nodo: %s, Puerto_Nodo: %s, Rutina de map: %s",ipNodo,puertoNodo,job->mapper); }else if(strcmp(rutina,"red")==0) { free(rutina); //Recibo los archivos y nodos en los que se ejecuta el reduce // int tamArchivosYNodos=0; // recibirYChequearConexion(conectarAMarta,&tamArchivosYNodos,sizeof(int)); // char *archivosYNodos=malloc(tamArchivosYNodos); // recibirYChequearConexion(conectarAMarta,archivosYNodos,tamArchivosYNodos); char *archivosYNodos; recibirTodo(conectarAMarta, (void**)&archivosYNodos); logCabeceraRecibe("Archivos y nodos"); int idReduce=0; recibirYChequearConexion(conectarAMarta,&idReduce,sizeof(int)); logCabeceraRecibe("Id de operacion reduce"); //Cargo la estructura hiloR t_hiloReducer *hiloR= malloc(sizeof(t_hiloReducer)); //Recibo si soy el ultimo reduce o no (Si: 1, No: 0) int soyUltimo = 0; recibirYChequearConexion(conectarAMarta,&soyUltimo,sizeof(int)); //Si soy el ultimo cargo en la estructura del hilo el path del resultado en FS if(soyUltimo) { hiloR->resultado=strdup(job->resultado); } hiloR->soyUltimo = soyUltimo; hiloR->ipNodo=strdup(ipNodo); hiloR->puertoNodo=strdup(puertoNodo); hiloR->reducer=strdup(job->reduce); hiloR->conectarAMarta=conectarAMarta; hiloR->archivosYNodos=strdup(archivosYNodos); hiloR->idReduce=idReduce; hiloR->resulReduce=strdup(resulOperacion); pthread_t hiloReducer; pthread_create(&hiloReducer,NULL,enviarReducerYObtenerResultado,hiloR); list_add(listaHilos,&hiloReducer); cantidadHilos++; free(archivosYNodos); free(resulOperacion); //Muestro que se creo un hilo logCreacionHiloReducer("Se creo un hilo reducer con parametros: Ip_Nodo: %s, Puerto_Nodo: %s, Rutina de reduce: %s, Archivo de resultado: %s",ipNodo,puertoNodo,job->reduce,job->resultado); } //recibirYChequearConexion(conectarAMarta,&fin,sizeof(int)); //logCabeceraRecibe("Termino el job?"); //Libero ip y puerto del nodo free(ipNodo); free(puertoNodo); } return EXIT_SUCCESS; }
void replanificar(int paraReplanificar,job* jobi,respuestaSolicitudTransformacion* respuestaArchivo, bool** matrix,int bloques,int nodos){ respuestaSolicitudTransformacion* respuestaTransfromacion = malloc(sizeof(respuestaSolicitudTransformacion)); respuestaTransfromacion->workers = list_create(); bool nodoConNumero(workerDesdeYama* worker){ return worker->numeroWorker == paraReplanificar; } workerDesdeYama* worker = list_find(respuestaArchivo->workers, (void*) nodoConNumero); void agregarBloque(bloquesConSusArchivosTransformacion* bloque){ bloquesConSusArchivosTransformacion* bloqueNuevo = malloc(sizeof(bloquesConSusArchivosTransformacion)); bloqueYNodo* nodoBloque = malloc(sizeof(bloqueYNodo)); nodoBloque->bloque= bloque->numBloque; nodoBloque->workerId = paraReplanificar; int nodoNuevo = nodoConOtraCopia(nodoBloque,matrix,nodos,bloques); if(nodoNuevo == -1){ log_trace(logger,"Fallo en replanificar nodo %d", paraReplanificar); finalizarJob(jobi,TRANSFORMACION,FALLO_TRANSFORMACION); } bool nodoYaCargado(workerDesdeYama* workerCargado){ return workerCargado->numeroWorker == nodoNuevo; } workerDesdeYama* nuevoWorker; if(list_any_satisfy(respuestaTransfromacion->workers,(void*)nodoYaCargado)){ nuevoWorker=list_find(respuestaTransfromacion->workers,(void*)nodoYaCargado); } else{ nuevoWorker = malloc(sizeof(workerDesdeYama)); nuevoWorker->numeroWorker = nodoNuevo; pthread_mutex_lock(&mutex_NodosConectados); infoNodo* infoNod = obtenerNodo(nodoNuevo); nuevoWorker->puerto= infoNod->puerto; nuevoWorker->ip.cadena = strdup(infoNod->ip.cadena); nuevoWorker->ip.longitud = infoNod->ip.longitud; pthread_mutex_unlock(&mutex_NodosConectados); list_add(respuestaTransfromacion->workers,nuevoWorker); nuevoWorker->bloquesConSusArchivos =list_create(); } bloqueNuevo->archivoTemporal.cadena = dameUnNombreArchivoTemporal(jobi->id,bloque->numBloque,TRANSFORMACION,nodoNuevo); bloqueNuevo->archivoTemporal.longitud = string_length(bloqueNuevo->archivoTemporal.cadena); bloqueNuevo->bytesOcupados = bloque->bytesOcupados; bloqueNuevo->numBloque = bloque->numBloque; bloqueNuevo->numBloqueEnNodo = bloque->numBloqueEnNodo; list_add(nuevoWorker->bloquesConSusArchivos,bloqueNuevo); log_trace(logger, "Replanifico bloque %i asignado al worker %i ",bloque->numBloque, nodoNuevo); pthread_mutex_lock(&mutexTablaEstados); bool regEnTabla(registroTablaEstados* reg){ return reg->job == jobi->id && reg->etapa == TRANSFORMACION && reg->bloque==bloque->numBloque; } registroTablaEstados* registroViejo =list_find(tablaDeEstados,(void*)regEnTabla); registroViejo->estado = ERROR; registroTablaEstados* registro = malloc(sizeof(registroTablaEstados)); registro->bloque= bloque->numBloque; registro->estado=EN_EJECUCION; registro->etapa= TRANSFORMACION; registro->job = jobi->id; registro->nodo= nodoNuevo; registro->rutaArchivoTemp = strdup(bloqueNuevo->archivoTemporal.cadena); list_add(tablaDeEstados,registro); pthread_mutex_unlock(&mutexTablaEstados); }