El 12 de junio de 2015, 2:58, Jose Caballero <jcaballero....@gmail.com>
escribió:

>
>
>
>
> On Jun 11, 2015, at 20:23, Chema Cortes <pych...@gmail.com> wrote:
>
>
>
> El 11 de junio de 2015, 16:06, Jose Caballero <jcaballero....@gmail.com>
> escribió:
>
>> [Pido perdon por adelantado por la ausencia de tildes. Teclado americano]
>>
>> Hola,
>>
>> me preguntaba si alguien sabria como hacer uso de os.walk( ) para
>> recorrer un "subtree" en el sistema de ficheros, pero con un timeout.
>> La razon para un timeout es, por ejemplo, para no quedarse esperando
>> para siempre si se trata de un sistema de ficheros montado (tipo AFS o
>> NFS) y el "server" no responde.
>>
>
> Una forma eficaz para evitar bloqueos en tu aplicación es usar "futures".
> En python3 vienen ya en la librería estándar y también de serie en anaconda:
>
> https://docs.python.org/3.4/library/concurrent.futures.html
> https://pypi.python.org/pypi/futures/
>
>
>
>
> Hola Chema,
>
> No conozco "futures", me lo tengo que mirar.
> Mi único 'constrain' es que estoy atado a python 2.6. No sé si será un
> problema. Lo sabré cuando me lo mire.
>

'futures' ha sido llevado de python3 a python 2.7 y 2.6. Lo deberías poder
usar sin problemas.


He estado haciendo unas pruebas para ver hasta era práctico. No sé si te
funcionará en tu caso, ya que los errores del sistema de ficheros
posiblemente bloqueen a todo el proceso.

En este código he intentado similar los timeouts. Se obtenien los
resultados a medida que los ficheros terminan de procesarse. Algunos
ficheros sufren aleatoriamente un retardo entre 1 y 10 segundos, y aparecen
al final del proceso precedidos por tantos asteriscos como segundos se han
retrasado. Si algún fichero supera el timeout de 8 segundos, se para todo
proceso.


from __future__ import print_function

import os
from os.path import join, getsize
from concurrent.futures import (ThreadPoolExecutor,
                                ProcessPoolExecutor,
                                TimeoutError,
                                as_completed)
from itertools import islice
import time
from random import random


def proc_file(root, dirs, files):

    try:
        size = sum(getsize(join(root, name)) for name in files)
        num = len(files)
        res = "{:8} bytes en {:3} ficheros de '{}'".format(size, num, root)

        # simulación de timeouts
        if random() > 0.9:
            espera = 10*random()
            time.sleep(espera)
            res = "*"*int(espera) + res

    except:

        res = "ERROR de acceso"

    return res


def main():

    dir_input = "/home"

    pool = ThreadPoolExecutor(40)
#    pool = ProcessPoolExecutor()

    with pool as ex:

        futures = (ex.submit(proc_file, root, dirs, files)
                    for (root, dirs, files) in os.walk(dir_input))

        while True:

            # Para evitar sobrecargar el proceso,
            # el iterador se consume en chunks de 100 elementos
            print("\n\n----------- NUEVO CHUNK -------------\n")
            chunk = list(islice(futures, 100))
            if len(chunk)==0:
                break

            try:
                for future in as_completed(chunk, timeout=8):
                    print(future.result())
            except TimeoutError:
                print("\n### ERROR: timeout exception\n")
                break

if __name__ == '__main__':
    main()
_______________________________________________
Python-es mailing list
Python-es@python.org
https://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Responder a