守望者:我在订阅之前缺少文件删除

时间:2018-01-28 04:45:28

标签: watchman

我在守望者中缺少删除。版本4.9.0,inotify。

我的测试代码:

#!/usr/bin/env python3

import pathlib
import pywatchman

w = pywatchman.client()

w.query('watch', '/tmp/z')
clock = w.query('clock', '/tmp/z')['clock']
print(clock)

q = w.query('subscribe', '/tmp/z', 'Buffy', {'expression':["since", clock],
"fields": ["name", "exists", "oclock", "ctime_ns", "new", "mode"]})
print(q)

f = pathlib.Path('/tmp/z/xx')

f.touch()
data = w.receive()
clock = data['clock']
print()
print('Touch file:')
print(data)
print('Clock:', clock)

f.unlink()
print()
print('Delete file:')
print(w.receive())
w.close()

w = pywatchman.client(timeout=99999)
q = w.query('subscribe', '/tmp/z', 'Buffy', {'expression':["since", clock],
"fields": ["name", "exists", "oclock", "ctime_ns", "new", "mode"]})
print(q)

print()
print('We request changes since', clock)
print(w.receive())
w.close()

我所看到的:

  1. 我们创建文件。我们收到新文件和目录更改的通知。 不可即可。我们注意到了#34;时钟"这个通知。

  2. 我们删除了该文件。我们收到文件删除的通知。 不可即可。不要收到目录更改的通知。

  3. 现在想象一下,在进程更新内部细节之前进程崩溃,但它记住了步骤1中通知的更改(目录更新和新文件的创建)。也就是说,处理事务1,但程序在处理事务2之前崩溃。

    1. 我们现在打开一个新的订阅者(请记住,我们正在模拟崩溃)并请求从步骤1开始更改。我正在模拟恢复,程序重新启动,注意事务1是正常的(文件存在)并请求更多更改(它应该删除)。

    2. 我希望得到一个文件删除,但我得到......没什么。的灾难性

    3. 文稿:

      $ ./watchman-bug.py 
      c:1517109517:10868:3:23
      {'clock': 'c:1517109517:10868:3:23', 'subscribe': 'Buffy', 'version': '4.9.0'}
      
      Touch file:
      {'unilateral': True, 'subscription': 'Buffy', 'root': '/tmp/z', 'files': [{'name': 'xx', 'exists': True, 'oclock': 'c:1517109517:10868:3:24', 'ctime_ns': 1517114230070245747, 'new': True, 'mode': 33188}], 'is_fresh_instance': False, 'version': '4.9.0', 'since': 'c:1517109517:10868:3:23', 'clock': 'c:1517109517:10868:3:24'}
      Clock: c:1517109517:10868:3:24
      
      Delete file:
      {'unilateral': True, 'subscription': 'Buffy', 'root': '/tmp/z', 'files': [{'name': 'xx', 'exists': False, 'oclock': 'c:1517109517:10868:3:25', 'ctime_ns': 1517114230070245747, 'new': False, 'mode': 33188}], 'is_fresh_instance': False, 'version': '4.9.0', 'since': 'c:1517109517:10868:3:24', 'clock': 'c:1517109517:10868:3:25'}
      {'clock': 'c:1517109517:10868:3:25', 'subscribe': 'Buffy', 'version': '4.9.0'}
      
      We request changes since c:1517109517:10868:3:24
      

      进程挂起,期待删除通知。

      我做错了什么?。

      感谢您的时间和知识!

1 个答案:

答案 0 :(得分:1)

问题在于您使用since表达式术语而不是通知守望者使用since生成器(新近度指数)。

区别是什么?您可以将此视为SQL中FROMWHERE子句之间的差异。 expression字段的意图类似于WHERE子句:它适用于匹配的结果并过滤掉它们,但您要做的是通过设置{来指定FROM子句查询规范中的{1}}字段。这无疑是一个微妙的差异。

解决方案是删除表达式术语并添加生成器术语,如下所示:

since

虽然我们没有关于pywatchman API使用的任何文档,但您可以从稍微更好的文档nodejs API中借用这些概念;这是一个相关的片段:

https://facebook.github.io/watchman/docs/nodejs.html#subscribing-only-to-changed-files