[DUDA] Problema de lectura en una tabla de MySQL

Iniciado por zagk, 26 Junio 2017, 17:56 PM

0 Miembros y 2 Visitantes están viendo este tema.

zagk

Hola, buen día. Tengo una interrogante con respecto a MySQL:

Actualmente estoy programando un Centro de Mensajería usando una librería externa y python. El problema radica en lo siguiente: la librería externa hace uso del módem y la base de datos, cada mensaje que recibe el módem, la librería lo procesa y lo envía a la base de datos automáticamente (la tabla llamado inbox, específicamente), ese es un servicio que se está ejecutando constantemente para detectar alguna recepción y guardarla automáticamente; ahora en python (al mismo tiempo que se ejecuta el servicio que os he dicho) se ejecuta un script que es un bucle que está leyendo la tabla inbox constantemente en busca de alguna actualización de la tabla (es decir, cuando llegue un mensaje nuevo) y cuando la tabla se actualiza (o debería), que llega un mensaje nuevo, lanza una notificación que se muestra en Windows, el ciclo en python es infinito (while True) por lo que nunca se detiene de leer la tabla inbox.

Cuando inicio ambos, funciona la recepción, almacenamiento y notificación perfectamente, pero una vez que han transcurrido 5 o 10 minutos pareciera que todo deja de funcionar aunque ninguno de los 2 muestra error; el módem no recibe mensajes, tampoco envía (también tengo una monitor que me muestra datos sobre el módem, tales como la señal, etc, este tampoco se actualiza).

Quisiera poder resolver esto, pero no sé lo que está sucediendo, pareciera que no permitiera tantas peticiones a la tabla (quizás por el bucle del script en python) o es que se le cae el servicio al módem.

¿Alguna idea sobre cómo solucionar este problema?

Orubatosu

No creo que sea un problema de límites, pero vamos que cosas mas raras se han visto

En lugar de leer constantemente una tabla que puede llegar a ser muy grande ¿has pensado en hacer un trigger que copie los nuevos mensajes cada minuto a otra tabla y trabajar sobre ella? mas que nada para mejorar un poco el tema de recursos. MySQL permite en uso de triggers y no debería de ser muy complicado hacer uno que se ejecute por ejemplo cada minuto y cree una tabla con los nuevos mensajes, y accedes a ella mas o menos al minuto. Claro que entonces ten en cuenta que debería de sincronizarse bien la cosa para no perder cosas por el camino, o quizás no borrar la nueva tabla sino hacerlo tras la comprobación

El comprobarla continuamente varias veces por segundo parece un poco exagerado, mas cuando hablamos de correos que normalmente no tienen una necesidad de comprobación constante. ¿Has probado a introducir un retardo entre lecturas primero a ver que pasa? Pongamos que compruebas la tabla cada minuto. Así al menos descartas que sea por saturación
"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998

zagk

Gracias por la respuesta. La cuestión es que, por ejemplo, ¿cómo hago en el caso de que me lleguen 20 mensajes seguidos en 20 o 30 segundos? Tengo que mostrarlos todos en las notificaciones, no puedo esperar una lectura de cada cierto tiempo, además, la notificación se lanza cada vez que se actualiza la tabla por lo que si el bucle entra en reposo durante 20 o 30 segundos y en ese período llega un mensaje, cuando se reinicie de nuevo pues no lo mostrará.

Lo que me pidieron fue que mostrara una notificación en Windows enseguida que llegara un mensaje a la base de datos.

Veo interesanto eso de los triggers que hablas, perdón por mi ignorancia pero apenas estoy empezando con MySQL. ¿Es posible de que cada vez que se actualice una tabla con un nuevo registro este se pase a otra tabla? Y así podría hacer el ciclo que te digo en esa tabla y el servicio de mensajería se ejecutaría sobre la otra tabla, que es la original.

¿Es posible? ¿Me sugerirías una mejor manera para realizar todo este proceso? Gracias por la respuesta, amigo.

MinusFour

Cita de: zagk en 26 Junio 2017, 17:56 PMel ciclo en python es infinito (while True) por lo que nunca se detiene de leer la tabla inbox.

Sin ningún sleep o algún timer? Por lo menos limita la peticion a 1 cada 30 segundos o asi.

Lo mas sencillo es que los clientes que hicieron la peticion para actualizar la tabla estén comunicados con los otros clientes. Por ejemplo, un cliente envia un mensaje al servidor (no MySQL, websockets, o TCP sockets) y el servidor le notifica al cliente en tiempo real del mensaje.

zagk

Hola MinusFour, la problemática que se presenta es la siguiente:

Los que quieren el Centro de Mensajería lo van a utilizar para un evento, en donde envían mensajes masivos a las personas sobre encuestas, etc. Un gran número de personas responderán al instante. El Centro de Mensajería utiliza un software de terceros para procesar todos los datos del módem y usa una base de datos propia para almacenar los mensajes enviados y recibidos, cada vez que el módem recibe un mensaje el software lo procesa y lo almacena en la tabla inbox de la base de datos: el script que hice lo que hace es verificar mediante un bucle cada vez que la tabla se actualiza (cada vez que la tabla inbox se actualiza quiere decir que hay un mensaje nuevo, con actualiza quiero decir que se añadió un nuevo registro) muestra el último registro que llegó y lo muestra en forma de notificación en Windows.

Con esto, por eso digo, si dejo que el bucle haga un sleep durante al menos 10 segundos y en ese período llega uno o varios mensajes, cuando vuelva a iniciar el bucle, luego del sleep, no los mostrará porque detectará que la tabla no se ha actualizado.

¿Crees que con eso de los triggers pueda hacer, por ejemplo, pasar todos los mensajes que se reciban (de la tabla inbox original) a otra tabla y crear un campo de comprobación que, por ejemplo, si un registro tiene ese campo en no visto el script lo tome y lo muestre en notificacion y ahora le cambie el estatus a visto, de allí cuando el script vuelva a recorrer la tabla detectará que ese mensaje ya ha sido notificado?

MinusFour

Cita de: zagk en 26 Junio 2017, 19:37 PM
Hola MinusFour, la problemática que se presenta es la siguiente:

Los que quieren el Centro de Mensajería lo van a utilizar para un evento, en donde envían mensajes masivos a las personas sobre encuestas, etc. Un gran número de personas responderán al instante. El Centro de Mensajería utiliza un software de terceros para procesar todos los datos del módem y usa una base de datos propia para almacenar los mensajes enviados y recibidos, cada vez que el módem recibe un mensaje el software lo procesa y lo almacena en la tabla inbox de la base de datos: el script que hice lo que hace es verificar mediante un bucle cada vez que la tabla se actualiza (cada vez que la tabla inbox se actualiza quiere decir que hay un mensaje nuevo, con actualiza quiero decir que se añadió un nuevo registro) muestra el último registro que llegó y lo muestra en forma de notificación en Windows.

Con esto, por eso digo, si dejo que el bucle haga un sleep durante al menos 10 segundos y en ese período llega uno o varios mensajes, cuando vuelva a iniciar el bucle, luego del sleep, no los mostrará porque detectará que la tabla no se ha actualizado.

¿Crees que con eso de los triggers pueda hacer, por ejemplo, pasar todos los mensajes que se reciban (de la tabla inbox original) a otra tabla y crear un campo de comprobación que, por ejemplo, si un registro tiene ese campo en no visto el script lo tome y lo muestre en notificacion y ahora le cambie el estatus a visto, de allí cuando el script vuelva a recorrer la tabla detectará que ese mensaje ya ha sido notificado?

Entonces tu problema es que no puedes distinguir si el mensaje lo has notificado o no. Lo que puedes hacer es alterar la tabla de inbox y agregar el campo de notificación, dejar que tengan un valor por defecto de falso y  simplemente actualizar el campo a verdadero cuando la notificación ocurra (es mas difícil si son varios puntos a los que tienes que notificar y la política que tengas).

De todas formas, lo mejor es si pudieras agregar un sistema de eventos al sistema que realiza y recibe todas estas peticiones.

zagk

Vale amigo, muchas gracias, haré eso que me has recomendado.

El Centro de Mensajería es controlado solo por una máquina, es decir, las notificaciones solo se ven allí, las notificaciones de los mensajes recibidos los recibe ella misma.

Gracias de nuevo, me has aclarado la duda.