我的 Linux 守护程序如何知道 Windows 程序何时停止写入我通过 SAMBA 访问的文件?

发布于 2024-08-22 12:42:17 字数 654 浏览 10 评论 0原文

我正在开发一个与 USPS 运输包裹交互的系统,称为 Dazzle。该系统的一部分包括一个监控守护进程,其目的是获取制表符分隔的值文件,将它们转换为 Dazzle 识别的 XML,并将它们传递给 Dazzle 进行标签生成。这部分工作得很好。然而,我还想做的是解析 Dazzle 生成的输出文件并将其导入数据库。

请注意,Dazzle 在 Windows 上运行。我的监控守护进程是用 Perl 编写的,在 Linux 上运行。我的 Linux 系统通过 Samba 安装了 Dazzle 的输入和输出目录。

Dazzle 开始写入输出文件的时间和完成时间之间存在可测量的延迟。我想知道如何等待 Dazzle 完成输出文件的写入?我尝试打开该文件并对其执行 flock($fh, LOCK_SH) 操作,但这似乎没有任何效果。

编辑:我根据下面“mobrule”的评论有一个想法。 Dazzle 以 XML 格式写入输出文件。货件中的每个包裹都附有标签,整个文档也附有标签。因此,如果我在文件完成之前开始读取文件,我只需等待适当的结束标记,然后再采取行动。

另外,我应该提一下我目前正在做的事情。当我检测到输出 XML 文件已创建时,我尝试解析它。如果解析失败,我会睡觉并重试。如果失败,我会睡两倍的时间,然后再试一次,依此类推。这在 64 秒超时的测试中效果很好。

I'm developing a system that interfaces with a USPS shipping package called Dazzle. Part of this system includes a monitoring daemon whose purpose is to take tab-separated value files, turn them into XML that Dazzle recognizes, and pass them to Dazzle for label generation. And this part works just fine. What I also want to do, however, is to parse the output file that Dazzle generates and import it into a database.

Note here that Dazzle runs on Windows. My monitoring daemon is written in Perl and runs on Linux. My Linux system has Dazzle's input and output directories mounted via Samba.

There is a measurable delay between the time Dazzle starts writing the output file and the time it's finished. What I want to know is how I can wait for Dazzle to finish writing the output file? I've tried opening the file and doing flock($fh, LOCK_SH) on it, but that didn't seem to do any good.

EDIT: I have an idea based on "mobrule"'s comment below. Dazzle writes an output file in XML. Each package in the shipment is enclosed in tags, and the entire document is enclosed in a tag. So, if I start reading the file before it's complete, I can simply wait for the appropriate closing tag before I take action.

Also, I should mention what I'm doing currently. When I detect that the output XML file has been created, I attempt to parse it. If that parsing fails, I sleep and try again. If that fails, I sleep twice as long, then try again, and so on. This has worked pretty well in testing with a 64 second timeout.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

¢好甜 2024-08-29 12:42:17

没有通用且可移植的方法来判断某个进程是否具有某个任意文件的打开文件句柄。您必须根据您对当地情况的了解做出判断。

在这种情况下,也许可以查询Windows机器上的进程表来查看“Dazzle”程序是否仍在运行。或者,也许您的经验为您提供了其他指导原则,例如“当输入合理时,Dazzle 的运行时间不会超过 20 秒”或“当 Dazzle 运行时,它每隔几秒更新一次文件。如果文件尚未更新”比如说 10 秒,那么 Dazzle 很有可能就完成了。”

但您不必等到 Dazzle 完成。在 Dazzle 写入文件的同时读取该文件是完全可以的 - 请参阅 perldoc对于seek函数,请注意“如何模拟tail -f”部分。然后您可以在 Dazzle 运行时更新数据库。

这样,如果您过于保守地猜测 Dazzle 何时完成,您的数据库仍然会及时更新,唯一的成本将是在 EOF 处对文件句柄进行一些无用的查找和读取调用。

There is no general and portable way to tell if some process has an open filehandle to some arbitrary file. You must make a judgement with your local knowledge of the situation.

In this case, it may be possible to query the process table on the Windows machine to see if the "Dazzle" program is still running. Or maybe your experience gives you other guidelines, like "Dazzle never takes more than 20 seconds to run when the input is reasonable" or "when Dazzle is running, it updates a file every couple of seconds. If the file hasn't been updated in, say, 10 seconds, then there's a very good chance that Dazzle is finished."

But you don't necessarily have to wait until Dazzle is finished. It is perfectly OK to read the file at the same time Dazzle is writing to it -- see the perldoc for the seek function, paying attention to the part about "how to emulate tail -f". Then you can update your database while Dazzle is running.

This way, if you are too conservative about guessing when Dazzle has finished, your database will still be updated in a timely manner, and the only cost will be some useless seek and read calls on a filehandle at EOF.

情愿 2024-08-29 12:42:17

这可能不是一个很好的解决方案,但您可以尝试重复重命名该文件,如果失败,请休眠一会儿。

This is probably not a great solution, but you could try to rename the file repeatedly, sleep for a bit if it fails.

陌伤ぢ 2024-08-29 12:42:17

您可以尝试使用 LOCK_EX 进行锁定 - 如果锁定失败,则意味着它仍在写入。就这样旋转,直到获得锁,眩晕就完成了。如果 Dazzle 关闭文件并使用追加模式再次打开它,这将会失败,因此这不是最好的解决方案。

You could try doing a lock w/ LOCK_EX - and if the lock fails, that means it's still being written. Spin like that until you obtain the lock, and dazzle should be done. This would fail if Dazzle ever closes the file and opens it again w/ append mode, so it's not the best solution.

分开我的手 2024-08-29 12:42:17

也许您可以让 Dazzle 写出一个虚拟文件或标志文件(它可以包含您想要的任何内容,例如日期/时间戳或序列号)来指示 Dazzle 已完成文件写入。然后您要做的就是测试该文件是否存在,以了解它是否已完成。

Maybe you can have Dazzle write out a dummy or flag file (it can contain anything you want like a date/time stamp or sequence number) to indicate that Dazzle has finished writing the file. Then all you do is test for the presence of this file to know that it is finished.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文