如何处理文件服务器竞争条件?

时间:2018-11-06 20:16:34

标签: php filesystems race-condition fileserver

我正在开发一个应用程序,该应用程序每1分钟轮询一次网络文件服务器(cifs)上的文件夹,以查找计划的cron作业中的新文件。

看到新文件时,它会暂时将其复制到本地文件系统中,然后对文件执行各种操作,然后再从本地和网络文件系统中删除它。

我担心在我的应用程序轮询网络文件夹的同时有人将文件添加到网络文件夹的情况下可能出现的竞争状况。这些文件非常小(1kb),因此在我轮询文件夹时仍然会复制文件,但这种情况可能会发生是非常罕见的。

我的问题是,这是合理的问题吗?如果是这样,我应该如何处理呢?

1 个答案:

答案 0 :(得分:0)

这是我解决问题的方式。

请注意,我在工作流程的多个方面遇到了此问题。第一个是我必须使用我的应用程序监视目录中的新文件,并确保它们已完成传输等。第二个是我必须将文件上载到另一个软件正在监视的目录中:a)我没有控制,并且b)非常陈旧,本身未进行任何验证。

要解决第一个问题:

在计划好的工作中,我扫描了目录中的所有文件,然后为每个文件生成了一个md5哈希,并将其与文件路径一起保存到数据库中的表中。

下次我的计划作业运行时(1分钟后),我从数据库中抓取了所有行(文件路径和哈希),检查该文件是否仍然存在,然后再次生成该文件的md5哈希。如果文件同时存在且散列相同,则对文件进行处理(并将其从目录中删除)。如果这两个失败之一,我将直接跳到循环中的下一个文件。

在处理完所有文件之后,我将截断为文件建立索引的表,然后再次为所有文件重新索引,以将它们重新保存到数据库中。一分钟后,我的工作又重新开始,使用了索引中的文件。

这样,我将永远不会处理上次作业未索引的文件。我相信可以肯定的是,如果文件哈希值在1分钟内没有变化,则文件传输完成,我可以使用它了。

要解决第二个问题:

为确保其他软件不会占用我可能正在上载的文件,我只是在服务器上创建了该软件未监控的另一个目录,然后将文件上载了该目录。文件传输完成后,我发出了将文件移动到受监视目录的move命令,并且由于移动是文件系统上的原子操作,因此在竞争状态下是安全的。