守望者是否能够发布到配置的命令,为什么它会向该命令发送文件?
例如:
有这样的事吗?
答案 0 :(得分:2)
不,它不能这样做。其原因对其设计非常重要。 TL; DR是一个比你想象的客户正确处理这些个别事件要复杂得多的事情,并且几乎在所有情况下你并不真正想要它们。
大多数文件观看系统都是抽象,只是将系统特定的通知信息转换为某种常见形式。他们不会或者根本没有交易,通知队列会溢出,并且不会为他们的客户提供可靠地响应这种情况的方法。
除此之外,文件系统可以在很短的时间内从多个并发线程或进程中进行许多不同的更改。这使得该区域极易出现难以管理的TOCTOU问题。例如,创建和写入文件通常会导致一系列有关该文件及其包含目录的通知。如果在此序列之后立即删除文件(可能是构建步骤中的中间文件),那么当您看到有关文件创建的通知时,很可能它已被删除。
Watchman获取通知的输入流并将其提供给文件系统的内部模型:观察文件的有序列表。每次收到通知时,watchman会将其视为应该去的信号并查看报告为已更改的文件,然后将该文件的条目移动到有序列表的最新末尾。
当您向Watchman询问有关文件系统的信息时,可能会或甚至可能存在来自内核的待处理通知。为了最小化TOCTOU并确保其状态是最新的,守望者会生成synchronization cookie并等待该通知在响应您的查询之前可见。
上述两件事的组合意味着守望者结果数据有两个重要属性:
让我们谈谈溢出案例。如果您的系统无法跟上文件更改的速度(例如:您有一个大项目并且非常快速地创建和删除文件并且系统负载很重),则操作系统不适合所有分配给监视的缓冲区资源中的挂起通知。当发生这种情况时,它会吹掉这些缓冲区并发送溢出信号。这意味着观看API的客户端已经错过了一些事件,并且不再与文件系统的状态同步。如果该客户端维护有关文件系统的状态,则它不再有效。
Watchman通过重新检查被监视的树并合成地将所有文件标记为已更改来解决这种情况。这会导致客户端的下一个查询查看树中的所有内容。我们称之为新实例结果集,因为它与您第一次查询时获得的视图相同。我们在结果中设置了一个标志,以便客户端知道这已经发生,并且可以采取适当的步骤来修复自己的状态。您可以通过query parameters配置此行为。
在这些新鲜实例结果集中,我们不知道任何给定文件是否真的发生了变化(它可能会以这样的方式发生变化&# 39; t通过lstat
检测,即使我们可以看到其元数据发生变化,我们也不知道这种变化的原因。
可能有多个事件导致给定文件出现在watchman提供的结果中的原因。我们不会单独记录它们,因为我们无法用无限的历史跟踪它们;想象一个文件,它每天都会每隔一秒递增一次。我们是否每天保留86400条更改条目并将其交付给我们的客户?如果有成千上万的这样的文件怎么办?我们必须截断这些数据,此时数据丢失会降低您对其进行推理的程度。
在所有这一切结束时,客户端除了尝试读取文件或查看其元数据之外,做很多事情是非常罕见的,一般来说,只有当文件停止更改时,他们才会这样做。对于此用例,watchman-wait,watchman-make和trigger都具有结算期的概念,导致更改通知在传递中延迟,直到文件系统停止更改为止。