Open GoogleCodeExporter opened 9 years ago
Otro sintoma:
Si al trabajo de procesamiento lo realiza el thread que escucha mensajes, el
bug no se manifiesta. Pero esta implementacion no es correcta ya que el thread
queda ocupado haciendo el trabajo y no puede recibir nuevos mensajes del
servidor.
Original comment by marjobe
on 21 Apr 2011 at 11:51
Hay dos opciones a alto nivel: sale mal, o llega mal.
Este último comentario (http://code.google.com/p/fud/issues/detail?id=5#c1)
confirma entonces que sale bien?
Cuál es la primer función que saca del socket?
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 1:05
X fav agregar links al código, a las funciones relevantes.
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 1:08
En respuesta al comentario 2.
Visto el sintoma, en el comentario 1, sabemos que en ese caso los paquetes
salen bien (y llegan bien). En cambio, cuando el procesamiento lo hace el
thread principal
(http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/client/distr
ibution_client.cpp#61) el error se manifiesta, por lo que en nuestra opinion:
los paquetes salen mal desde el cliente.
Envio y recepcion de paquetes lo confiamos a ANA:
la funcion que envia es
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/a
na/client/ana_distribution.cpp#69 y
la funcion que el listener llama cuando se recibe es
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/a
na/client/ana_distribution.cpp#84
Original comment by marjobe
on 22 Apr 2011 at 12:39
No entiendo el razonamiento:
emisor -> receptor: MAL
emisor -> receptor2: BIEN (receptor2 sería cuando cambian el thread)
Por qué deducen que el problema está en el emisor, cuando cambiando el
receptor funciona?
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 5:36
pls see review comments in http://code.google.com/p/fud/source/detail?r=526
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 5:46
Respuesta comentario 5.
Tener en cuenta que el escenario del bug es cuando el cliente envia mensajes
intermedios al servidor, por lo tanto, el emisor es el cliente y receptor es el
servidor.
Seria asi:
emisor -> receptor: MAL
emisor2 -> receptor: BIEN (emisor2 seria cuando el thread dedicado a
escuchar largado aca
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/a
na/client/ana_distribution.cpp#60 hace todo el trabajo)
Dado el grafico de arriba, deducimos que el problema esta en el emisor ya que
cambiando al emisor2, funciona.
Original comment by marjobe
on 22 Apr 2011 at 6:26
OK, por favor expliquen (de ser posible con un diff) cuándo funciona y cuándo
no, porque no logro distinguir la diferencia en el código.
Por otro lado, xfav implementen las recomendaciones que hice en el código,
especialmente los checkeos (de código de error, de mili::substr, etc.).
Consideren ADEMAS, y luego de estos cambios de código, correr todo con
valgrind para verificar que no estén leyendo un paquete liberado y por lo
tanto lean basura.
Todo tiene olor a un mutex de menos.
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 6:39
(agreguen el diff attacheado acá xfav, y expliquen la dirección del diff:
buggy->working, o al revés)
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 6:40
La funcion
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/a
na/client/ana_distribution.cpp?spec=svn526&r=526#84 es el punto de entrada del
cliente, la cual se ejecuta cuando llega un mensaje entrante.
La idea de la implementacion (que no funciona) es meter el mensaje que llega en
una cola, que luego otro thread (el encargado de procesar trabajos) sacara para
su posterior tratamiento.
El diff adjunto cambia el comportamiento de la implementacion explicada arriba,
de forma que el mensaje entrante ahora NO es insertado en una cola, sino que
recibe y procesa el trabajo el mismo listener (por lo que en este caso solo
hablamos de un solo thread que hace todo).
El problema de este parche es que NO es una solucion valida ya que tenemos que
tener al listener apto para la escucha de otros mensajes en el medio del
procesamiento de un trabajo.
[ver working-fud.diff]
Original comment by marjobe
on 22 Apr 2011 at 7:46
Attachments:
Ahora sí, CLARÍSIMO. Lo analizamos. Buen desarrollo del issue.
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 7:49
Por favor mientras tanto proceder con los cambios de código recomendados.
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 7:50
Ok. Anda haciendo un update porque ya estuvimos tapando unos warnings.
Y seguiremos con las otras recomendaciones de chequeo...
Original comment by marjobe
on 22 Apr 2011 at 7:52
Con esto parecería ser que las opciones son:
a) el problema está en la inserción en la cola (add_message)
b) en el momento, o después de, la extracción de la cola (el otro thread).
Ahora hay que determinar de qué lado está el problema, en este sentido.
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 7:54
(agrego)
c) el problema está tanto en la inserción o extracción de la cola,
indiferentemente, POR SER UN PROBLEMA DE SINCRONIZACIÓN de la misma.
Original comment by danielgutson@gmail.com
on 22 Apr 2011 at 8:06
Por favor pega un link al add_message. El google code parece buscar sobre trunk
nomas.
Como te decia, mi impresion es que la memoria que termina usando para el
mensaje se dealoca, por algun problema asociado a los buffers y el
multi-threading.
Como nota, cuando ANA llama a tu handle_receive te pasa un buffer que en
realidad es un auto_ptr:
http://code.google.com/p/ana-net/source/browse/trunk/src/api/buffers.hpp#172
http://code.google.com/p/ana-net/source/browse/trunk/src/api/buffers.hpp#49
El auto_ptr se destruye, junto con su memoria de soporte, en algun momento
despues de q termina handle_receive, provisto que vos no hayas copiado el
puntero, o sea, que si usas:
buffer->base() para memorizarte la base del buffer, eventualmente ese char*
queda apuntando a memoria no allocada.
Original comment by billybiset
on 27 Apr 2011 at 1:01
Otro sintoma o solucion ?
Comentando este set_timeouts:
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/a
na/client/ana_distribution.cpp#59 funka !
A partir de la premisa de que no sabemos cuanto tiempo puede el cliente tardar
mandando mensajes al servidor, pienso que la solucion es sacar esta linea o
subir exageradamente el tiempo del timeout.
Original comment by marjobe
on 2 May 2011 at 2:23
Hiciste las modificaciones de código que sugerí?
Por favor, prolijamente un paso por vez.
Original comment by danielgutson@gmail.com
on 2 May 2011 at 5:18
Con respecto a las modificaciones de código que sugeriste: algunas fueron
implementadas r527 y las demas las hice pero no las subi. Igual el
comportamiento del bug no varió.
Lo que si modificó el comportamiento del bug es lo enunciado en el comment 17.
Dame una opinion.
Original comment by marjobe
on 2 May 2011 at 7:44
No tengo aún el análisis suficiente para relacionar el c17 y el c10. Billy?
En cuanto a las modificaciones sugeridas, me refería especialmente a si
(ahora?) que checkeás el código de error, reporta algo.
Original comment by danielgutson@gmail.com
on 2 May 2011 at 7:52
Un pedido: podrías resumir porfa cuáles son los threads involucrados, tanto
del lado del cliente como del servidor, para terminar de entender c17 y c10?
Básicamente: threads involucrados (rol que cumple), en dónde corre, timeouts,
y queues.
Me pierdo en qué timeouts de qué handle de qué cosa.
Original comment by danielgutson@gmail.com
on 2 May 2011 at 7:56
Un pedido: podrías resumir porfa cuáles son los threads involucrados, tanto
del lado del cliente como del servidor, para terminar de entender c17 y c10?
Básicamente: threads involucrados (rol que cumple), en dónde corre, timeouts,
y queues.
Me pierdo en qué timeouts de qué handle de qué cosa.
Original comment by danielgutson@gmail.com
on 2 May 2011 at 7:56
Sobre c17:
Los timeouts de ANA se usan para lo siguiente:
Le 'seteas' un timeout de 10 segundos a las operaciones, entonces si te mandas
a enviar algo y para los 10 segundos no se termino de mandar, te informa que
hubo timeout, conviene para conexiones malas. Su valor deberia ser empirico
segun el uso que se le da. Quizas 10 segundos para mensajes grandes es poco, se
pueden no poner timeouts (comentando esa linea) o usar timeouts relativos al
tamaño del mensaje:
http://code.google.com/p/ana-net/source/browse/trunk/src/api/timers.hpp#238
y
http://code.google.com/p/ana-net/source/browse/trunk/src/api/timers.hpp#113
(se puede poner, por ej, 1 segundo por cada kilobyte o algo raro asi)
El miercoles analizo la relacion c17 / c20, estoy pasado entre mudanza y
problemas de internet.
Original comment by billybiset
on 2 May 2011 at 7:59
Marian, para ver threads, en gdb:
info threads
t N (donde N es el thread que queres)
ANA corre un thread para llamar los callbacks por cada operacion de run() sobre
el objeto ana::client o ana::server.
Original comment by billybiset
on 2 May 2011 at 8:00
lo mejor es que attachees el output del siguiente comando en gdb:
t a a bt
(uso la primer letra de cada comando: [t]hreads [a]pply [a]ll backtrace)
a lo mejor quieras hacer antes:
set logging file mariano
set logging on
set height 0
y simplemente después attachear acá el archivo mariano
Original comment by danielgutson@gmail.com
on 2 May 2011 at 8:11
Con respecto a c21, threads involucrados:
Lado cliente
* Thread principal: ejecuta este metodo -->
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/client/distri
bution_client.cpp#61 que basicamente chequea la queue de mensajes y segun el
tipo de msg hace algo.
* Thread escuchador (nace aca
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/a
na/client/ana_distribution.cpp#58) y es de ANA, cada vez que llega un msg del
server ejecuta handle_receive -->
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/a
na/client/ana_distribution.cpp#82 la cual mete a la queue de mensajes el
paquete que viene desde del server. Este thread setea(ba) el timeout de ANA en
10 segundos (explicacion del timer en c23).
Lado servidor
* Thread escuchador (nace aca
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/a
na/server/ana_clients_manager.cpp#56) es de ANA, cada vez que llega un mensaje
desde un cliente llama a handle_receive
(http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/
ana/server/ana_clients_manager.cpp#69), el cual llama al handle_response del
cliente en particular
(http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/server/clien
t_proxy.cpp#73).
Como adjuntos estan los outputs del gdb (segun c25) del server y del client.
De todas formas: el bug ESTA SOLUCIONADO. O para uds no ?
Original comment by marjobe
on 2 May 2011 at 9:09
Attachments:
No sé si el bug está solucionado, porque no sé siquiera si sabemos
exactamente cuál es el problema.
La idea de los attachments q te dije era ver el bt (por eso "t a a bt"); lo q
attacheaste no dice nada :(
Con esto ya sí podemos terminar de hacer el análisis.
Original comment by danielgutson@gmail.com
on 2 May 2011 at 9:43
Workaround
Una solucion alternativa para este bug es NO setear un tiempo fijo por cada
operacion de envio del cliente. Este método, que setea una determinada
tolerancia de tiempo, pertenece a la libreria ANA.
¿ Como se implementó esta solución alternativa ?
Comentando esta linea -->
http://code.google.com/p/fud/source/browse/branches/FuD-duplex/src/middlewares/a
na/client/ana_distribution.cpp#58 . Fue hecho en r546.
Si se encuentra una solución definitiva, se deberia descomentar la misma
linea, por lo que FuD funcionaria con el set_timeouts de tiempo fijo.
Original comment by marjobe
on 10 May 2011 at 3:20
Original issue reported on code.google.com by
marjobe
on 21 Apr 2011 at 11:25