Paralelismo en crontab

37 views
Skip to first unread message

Daniela Blanco

unread,
May 3, 2017, 2:05:26 PM5/3/17
to codeignit...@googlegroups.com
Hola, quizás es un tema que escapa a CI puro. Pero estoy necesitando programar tareas (cron) que se ejecuten en paralelo para optimizar tiempos. Hasta posiblemente disponga de diferentes procesadores/cors para hacerlo.

Conocen alguna librería que sirva? O framework complementario. Actuamente para ejecutar cron con CI tengo una librería básica. Faltaría aprovechar el paralelismo.

Cualquier comentario es bienvenido. Saludos

Carlos Romero

unread,
May 3, 2017, 2:16:16 PM5/3/17
to CodeIgniter-spanish
Hace tiempo hice un CURL múltiple para poder hacerlo... era configurable y lo crecíamos hasta el núm max de núcleos.. si te interesa, la busco

Josepzin Ungoliante

unread,
May 3, 2017, 4:24:30 PM5/3/17
to CodeIgniter-spanish
Nunca en la vida hice algo así y tampoco sabía que se podía controlar desde PHP, muy interesante!

Daniela Blanco

unread,
May 3, 2017, 5:02:18 PM5/3/17
to CodeIgniter-spanish
Gracias Carlos, sin duda seria de mucha ayuda. Y cualquier cambio que haga lo puedo volver a compartir si aporta.

Aguardo el contacto, saludos

Ever Daniel Barreto Rojas

unread,
May 3, 2017, 6:00:03 PM5/3/17
to codeignit...@googlegroups.com
Hola Daniela!

definitivamente es posible hacerlo en CodeIgniter, la forma en que yo lo encararía es de la siguiente forma:

1) Asumiendo que las tareas deben realizarse en intervalos discretos, podés definir un cronjob que llama a una controlador/método específico de tu app. En tu controlador, podés verificar que se está invocando vía CLI para evitar que alguien lo dispare accidentalmente desde la web. Si el trabajo depende en base a un evento o una acción del usuario, podés

2) En tu controlador/método específico, podés generar las tareas de ejecución en colocarlas en una cola de mensajes, por ejemplo, en beanstalkd

3) Utilizando supervisor (asumiendo que estás usando Linux) podés definir uno o más workers (que de nuevo, pueden ser controladores/métodos específicos que vos definas) que están "escuchando" en la cola de mensajes. Ni bien coloques un "mensaje" o "job" en la cola, un worker va a tomar ese mensaje y va a empezar a trabajar en esa tarea. Si por ejemplo, tenés configurado 4 "workers" eso significa que podes tener hasta 4 procesos trabajando en paralelo

Se entiende?

Sino avisame y lo explico mejor, yo ya hice esto varias veces.

---
Ever Daniel Barreto Rojas
everdaniel at gmail dot com

--
Antes de responder revisa: http://es.wikipedia.org/wiki/Netiquette
Regístrate en el Censo CI: http://bit.ly/miembroscodeigniteres
---
Has recibido este mensaje porque estás suscrito al grupo "CodeIgniter-spanish" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a codeigniter-spanish+unsub...@googlegroups.com.
Para publicar en este grupo, envía un correo electrónico a codeigniter-spanish@googlegroups.com.
Visita este grupo en https://groups.google.com/group/codeigniter-spanish.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/codeigniter-spanish/CAG7fWz8JiDviC-2n9LwpL6eShqxV0DFK4aDp0E0vv%3Dr2BAFbOQ%40mail.gmail.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Carlos Romero

unread,
May 3, 2017, 6:39:34 PM5/3/17
to CodeIgniter-spanish
Ahí te va... la idea es tener un arreglo de "n" elementos que vas a procesar, y los vas a juntar en grupos de "x", donde "x" es el número de multiprocesos a ejecutar... luego preparas un multi_curl, y lo ejecutas hasta que termine... si puedes ver los núcleos de los procesadores en alguna utilería, es bien padre ver cómo se activan y se duermen
... espero sea de utilidad..




// Obtengo mis fotos a procesar .. todas ellas .. creo eran 20

        $fotos = $this->dirm->getFotosAProcesar($this->num_batch_fotos);
        
// Preparo variables para hacer mis grupos de fotos
// num_multiprocesos es el número de procesos en paralelo que quieras ejecutar... en este caso son 4 núcleos

        $k = 0;
        $l = 0;
        $tempArr = array();
        
        /**
         * Ordenar el array en modo que se pueda procesar con un foreach y venga en grupos de "x" elementos
         * 
         * siendo "x" el número de multiprocesos que se quiere ejecutar.
         */
        foreach ($fotos as $row_foto) {
            $tempArr[$k][$l] = $row_foto;
            $l++;
            if($l==$this->num_multiprocesos){
                $l = 0;
                $k++;
            }
            
        }
        
        /**
         * Ejecutar con multicurl las peticiones en paralelo al servicio de procesamiento
         */
        $fotos_procesadas = 0;
        $res    = array();

        foreach ($tempArr as $kx => $row){
            
            $mh = curl_multi_init();
            
            $curl_array = array();
            
// Preparas el arreglo para multicurl y lo agregas al handle, con un key $id_pp para poder indizarlo, y haces un URL único para cada petición .. 
// en este caso, mando el Id de cada foto a procesar


            foreach ($row as $l=>$foto) {
                
                $url    = site_url('proc/doProcesa/'.$foto->IdPorProcesar);
                $id_pp  = $foto->IdPorProcesar;
                
                $curl_array[$id_pp] = curl_init($url);            

                curl_setopt($curl_array[$id_pp],CURLOPT_TIMEOUT,10);
                curl_setopt($curl_array[$id_pp], CURLOPT_RETURNTRANSFER, true);

                curl_multi_add_handle($mh,$curl_array[$id_pp]);
                
            }
            $running = null;
// Ejecutas el CURL

            do {
                usleep(10000); 
                curl_multi_exec($mh,$running);
            } while($running > 0); 

            foreach ($row as $l=>$foto) {
                $kk = $foto->IdPorProcesar;

// Aquí lo mandas llamar con el multi_getcontent

                $res[$kx][$kk] = json_decode(curl_multi_getcontent($curl_array[$kk])); 
            }
            foreach ($row as $l=>$foto) {
                $kkl = $foto->IdPorProcesar;
                curl_multi_remove_handle($mh, $curl_array[$kkl]);
            }
            curl_multi_close($mh);
             
        }
        
// Aquí contabilizo las fotos procesadas...

        foreach ($res as $n=>$row_proc) {
            foreach ($row_proc as $nn=>$det) {
                if(!$det->error){
                    $fotos_procesadas++;
                }
            }
        }

Daniela Blanco

unread,
May 3, 2017, 7:08:23 PM5/3/17
to codeignit...@googlegroups.com
Se entiende. No tengo experiencia definiendo workers. Debere investigar por ahi.

Algun ejemplo en CI para usar de guia?

El 3 de mayo de 2017, 18:59, Ever Daniel Barreto Rojas <everd...@gmail.com> escribió:
Hola Daniela!

definitivamente es posible hacerlo en CodeIgniter, la forma en que yo lo encararía es de la siguiente forma:

1) Asumiendo que las tareas deben realizarse en intervalos discretos, podés definir un cronjob que llama a una controlador/método específico de tu app. En tu controlador, podés verificar que se está invocando vía CLI para evitar que alguien lo dispare accidentalmente desde la web. Si el trabajo depende en base a un evento o una acción del usuario, podés

2) En tu controlador/método específico, podés generar las tareas de ejecución en colocarlas en una cola de mensajes, por ejemplo, en beanstalkd

3) Utilizando supervisor (asumiendo que estás usando Linux) podés definir uno o más workers (que de nuevo, pueden ser controladores/métodos específicos que vos definas) que están "escuchando" en la cola de mensajes. Ni bien coloques un "mensaje" o "job" en la cola, un worker va a tomar ese mensaje y va a empezar a trabajar en esa tarea. Si por ejemplo, tenés configurado 4 "workers" eso significa que podes tener hasta 4 procesos trabajando en paralelo

Se entiende?

Sino avisame y lo explico mejor, yo ya hice esto varias veces.

---
Ever Daniel Barreto Rojas
everdaniel at gmail dot com

El 3 de mayo de 2017, 14:05, Daniela Blanco <danibl...@gmail.com> escribió:
Hola, quizás es un tema que escapa a CI puro. Pero estoy necesitando programar tareas (cron) que se ejecuten en paralelo para optimizar tiempos. Hasta posiblemente disponga de diferentes procesadores/cors para hacerlo.

Conocen alguna librería que sirva? O framework complementario. Actuamente para ejecutar cron con CI tengo una librería básica. Faltaría aprovechar el paralelismo.

Cualquier comentario es bienvenido. Saludos

--
Antes de responder revisa: http://es.wikipedia.org/wiki/Netiquette
Regístrate en el Censo CI: http://bit.ly/miembroscodeigniteres
---
Has recibido este mensaje porque estás suscrito al grupo "CodeIgniter-spanish" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a codeigniter-spanish+unsubscribe...@googlegroups.com.

Para publicar en este grupo, envía un correo electrónico a codeigniter-spanish@googlegroups.com.
Visita este grupo en https://groups.google.com/group/codeigniter-spanish.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/codeigniter-spanish/CAG7fWz8JiDviC-2n9LwpL6eShqxV0DFK4aDp0E0vv%3Dr2BAFbOQ%40mail.gmail.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

--
Antes de responder revisa: http://es.wikipedia.org/wiki/Netiquette
Regístrate en el Censo CI: http://bit.ly/miembroscodeigniteres
---
Has recibido este mensaje porque estás suscrito a un tema del grupo "CodeIgniter-spanish" de Grupos de Google.
Para cancelar la suscripción a este tema, visita https://groups.google.com/d/topic/codeigniter-spanish/1Do79EM3Fw4/unsubscribe.
Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a codeigniter-spanish+unsub...@googlegroups.com.

Para publicar en este grupo, envía un correo electrónico a codeigniter-spanish@googlegroups.com.
Visita este grupo en https://groups.google.com/group/codeigniter-spanish.

Para acceder a más opciones, visita https://groups.google.com/d/optout.



--
Daniela Blanco
Reply all
Reply to author
Forward
0 new messages