Hola a todos,
Al monitorear una carpeta dentro de un QNAP, puedo obtener eventos para archivos recién creados. Sin embargo, si el nuevo archivo es un directorio, el perro guardián falla con un error del sistema.
Sospecho que se debe a que el archivo todavía se está copiando, pero esa no debería ser una razón para bloquear al oyente.
La aplicación se ejecuta en Windows 8.1 Pro.
Versión de firmware de QNAP: 3.7.2 Build 20120719
Seguimiento de pila:
Exception in thread Thread-3:
Traceback (most recent call last):
File "C:\Python34\lib\threading.py", line 920, in _bootstrap_inner
self.run()
File "C:\Python34\lib\site-packages\watchdog-0.8.3-py3.4.egg\watchdog\observers\api.py", line 146, in run
self.queue_events(self.timeout)
File "C:\Python34\lib\site-packages\watchdog-0.8.3-py3.4.egg\watchdog\observers\read_directory_changes.py", line 77, in queue_events
winapi_events = read_events(self._handle, self.watch.is_recursive)
File "C:\Python34\lib\site-packages\watchdog-0.8.3-py3.4.egg\watchdog\observers\winapi.py", line 347, in read_events
buf, nbytes = read_directory_changes(handle, recursive)
File "C:\Python34\lib\site-packages\watchdog-0.8.3-py3.4.egg\watchdog\observers\winapi.py", line 307, in read_directory_changes
raise e
File "C:\Python34\lib\site-packages\watchdog-0.8.3-py3.4.egg\watchdog\observers\winapi.py", line 303, in read_directory_changes
ctypes.byref(nbytes), None, None)
File "C:\Python34\lib\site-packages\watchdog-0.8.3-py3.4.egg\watchdog\observers\winapi.py", line 108, in _errcheck_bool
raise ctypes.WinError()
OSError: [WinError 58] The specified server cannot perform the requested operation.
El mismo problema por aquí, con un WinError 64 y el mensaje: El nombre de red especificado ya no está disponible. Esto sucede cuando la carpeta se entrega desde un servidor de archivos que deja de estar disponible (recurso compartido SMB).
¿Cómo podríamos detectar este tipo de error para volver a intentar adjuntar un observador más tarde?
Ahora también estoy buscando una solución para retrasar / reintentar el hilo de dirwatcher en:
OSError: [WinError 64] El nombre de red especificado ya no está disponible
Tuve el mismo problema en el que recibía el mensaje WinError 64 al monitorear un recurso compartido de archivos remoto. Terminé creando una pequeña envoltura alrededor de la clase watchdog.utils.BaseThread que me permite detectar el error y recuperarme. Luego parcheo la clase BaseThread original con mi envoltorio antes de crear un Observer. En mi caso específico, capturo las excepciones que podrían ocurrir en el método de ejecución y las agrego a una cola para consumirlas en un hilo diferente. Es una solución hacky, pero no hay muchas opciones sin cambios en el código fuente.
import logging
import threading
import watchdog.utils
logger = logging.getLogger(__name__)
class BaseThreadWrapper(watchdog.utils.BaseThread):
"""
Wrapper around watchdog BaseThread class.
"""
queue = None
def __init__(self):
super(BaseThreadWrapper, self).__init__()
self._original_run = self.run
self.run = self.run_wrapper
def run_wrapper(self):
try:
self._original_run()
except Exception as e:
logger.exception('%s thread exited with error',
threading.current_thread().name)
self.queue.put(e)
watchdog.utils.BaseThread = BaseThreadWrapper
¿Qué solución (cambios de código) le gustaría ver en el perro guardián?
Comentario más útil
Ahora también estoy buscando una solución para retrasar / reintentar el hilo de dirwatcher en:
OSError: [WinError 64] El nombre de red especificado ya no está disponible