[pyar] Timeouts para codigo de terceras partes: PyThreadState_SetAsyncExc?

Roberto Alsina ralsina en netmanagers.com.ar
Mar Ene 6 15:31:27 ART 2015


On 06/01/15 15:14, Andres Riancho wrote:
> Al fin termine haciendo esto [0]:
>
>   * Creo un multiprocessing.Pool
>   * Creo un "shared dict" donde el subproceso guarda que es lo que esta
> procesando y su pid [1]
>   * El parsing se hace en el subproceso, por medio del pool. El main
> process se queda esperando a que el subprocess termine [2]
>   * En caso de que no termine en menos que el timeout, se mata al
> proceso usando la informacion guardada en [1](*)
>   * Ya que puede haber varios procesos en el pool, hay una minima sync
> para que dos distintos threads del main process no manden a parsear la
> misma cosa [3], esto lo arme con eventos.
>
> Lo que no me gusto de mi implementacion:
>
>    * `os.kill(pid, signal.SIGTERM)`, en alguna race condition extraña,
> puede llegar a matar un proceso que no tiene nada que ver con w3af,
> oops!

Por eso no tenés que matar los procesos del pool así, si no con 
Process.terminate()

>    * No investigue suficiente sobre el Pool, pero asumo que va a
> bancarse que le mate los hijos, spawnear nuevos, no tener memory
> leaks, etc.
>
> Ya que en los parsers el "dom" generado por lxml no se requiere en
> todos los casos lo que hice fue que solo en el main process se llame a
> get_dom() , por lo que no tengo problemas con la serializacion
>
> (*) No encontre una mejor manera de saber quien del pool esta
> corriendo que cosa como para matarlo
>
> [0] https://github.com/andresriancho/w3af/blob/166dbff350f4922e0c1210d6348c2d30c5678ca2/w3af/core/data/parsers/parser_cache.py
> [1] https://github.com/andresriancho/w3af/blob/166dbff350f4922e0c1210d6348c2d30c5678ca2/w3af/core/data/parsers/parser_cache.py#L234
> [2] https://github.com/andresriancho/w3af/blob/166dbff350f4922e0c1210d6348c2d30c5678ca2/w3af/core/data/parsers/parser_cache.py#L137
> [3] https://github.com/andresriancho/w3af/blob/166dbff350f4922e0c1210d6348c2d30c5678ca2/w3af/core/data/parsers/parser_cache.py#L186
>
> 2015-01-06 0:03 GMT-03:00 Alejandro Santos <listas en alejolp.com>:
>> 2015-01-06 3:49 GMT+01:00 Alejandro Santos <listas en alejolp.com>:
>>> 2015-01-06 0:30 GMT+01:00 Andres Riancho <andres.riancho en gmail.com>:
>>>>      Gracias por la buena propuesta, despues de enviar el email estuve
>>>> viendo eso y creo que en una gran cantidad de casos sirve pero... a mi
>>>> no me va a servir ya que la respuesta de la libreria es un objeto que
>>>> NO se puede serializar, por lo que no lo puedo pasar entre el
>>>> subproceso (multiprocessing.Process) y el proceso principal.
>>>>
>>>>      Alguna idea de como hacer un workaround de eso? Estuve leyendo un
>>>> poco sobre multiprocessing.Namespace, pero no estoy seguro, deberia
>>>> probarlo.
>>>>
>>> ¿Qué es lo que la librería devuelve, un file handle o socket? Contame
>>> un poco más en detalle cómo funciona. Lo que podés hacer es mover tu
>>> lógica de procesamiento dentro de bad_func.
>>>
>>> Por ejemplo, si tu librería devuelve un socket que tenés que usar,
>>> hacele read y write dentro de bad_func.
>>>
>> Una alternativa sería que, en vez de tener un timeout, hacer un
>> watchdog con una especie de ping dentro de bad_func. Usás una Queue
>> para avisarle al proceso padre que la ejecución sigue funcionando, y
>> cuando pasa determinado tiempo sin respuesta el padre mata al proceso
>> hijo:
>>
>> import multiprocessing
>> from Queue import Empty
>> import time
>>
>> def exec_with_timeout(f, args, timeout):
>>      Q = multiprocessing.Queue()
>>      p = multiprocessing.Process(target=f, args=(Q, args))
>>      p.start()
>>      while p.is_alive():
>>          try:
>>              if not: Q.pop(True, timeout):
>>                  break
>>          except Empty:
>>              break
>>
>>      if p.is_alive():
>>          p.terminate()
>>
>> def bad_func(q, t):
>>      while True:
>>          time.sleep(t)
>>          q.push(True) # Le avisamos al padre que todo OK.
>>
>> exec_with_timeout(bad_func, (5.0, ), 0.1)
>>
>>
>>
>>
>> --
>> Alejandro Santos
>> _______________________________________________
>> pyar mailing list pyar en python.org.ar
>> http://listas.python.org.ar/listinfo/pyar
>>
>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>
>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de Argentina - http://www.usla.org.ar
>
>



More information about the pyar mailing list