Olá a todos,
Ao monitorar uma pasta dentro de um QNAP, posso obter eventos para arquivos recém-criados. No entanto, se o novo arquivo for um diretório, o watchdog trava com um erro do sistema.
Suspeito que seja porque o arquivo ainda está sendo copiado, mas isso não deve ser motivo para travar o ouvinte.
O aplicativo está sendo executado no Windows 8.1 Pro.
Versão do firmware QNAP: 3.7.2 Build 20120719
Rastreamento de pilha:
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.
O mesmo problema por aqui, com um WinError 64 e a mensagem: O nome de rede especificado não está mais disponível. Isso acontece quando a pasta é servida por um servidor de arquivos que se torna indisponível (compartilhamento SMB).
Como poderíamos detectar esse tipo de erro, para tentar novamente anexar um observador mais tarde?
Também estou procurando uma solução para atrasar / repetir o thread do dirwatcher em:
OSError: [WinError 64] O nome de rede especificado não está mais disponível
Tive o mesmo problema de receber a mensagem WinError 64 ao monitorar um compartilhamento de arquivo remoto. Acabei criando um pequeno invólucro em torno da classe watchdog.utils.BaseThread que me permite detectar o erro e me recuperar. Em seguida, faço um monkeypatch da classe BaseThread original com meu wrapper antes de criar um Observer. No meu caso específico, pego todas as exceções que podem acontecer no método run e as adiciono a uma fila para serem consumidas em um thread diferente. É uma solução hacky, mas não há muitas opções sem mudanças no código-fonte.
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
Que solução (mudanças de código) você gostaria de ver no watchdog?
Comentários muito úteis
Também estou procurando uma solução para atrasar / repetir o thread do dirwatcher em:
OSError: [WinError 64] O nome de rede especificado não está mais disponível