Erlang:创建filewatcher

Ant*_*iev 5 erlang

我必须在Erlang中实现文件监视器功能:应该有一个进程列出文件,如果特定目录,并在文件出现时执行某些操作.

我看看OTP.所以目前我有以下想法:1.创建将控制gen_servers的Supervisor(每个文件夹一个服务器)2.为我想要监视的每个文件夹创建WatchServer - gen_server.3.创建ProcessFileServer - 应该对文件执行某些操作的gen服务器)假设复制到不同的folder =

所以第一个问题:WatchServer不应该等待请求,它应该在预定义的时间间隔内生成一个.

目前我在init/1函数中创建了一个计时器,并在handle_info函数中处理on_timer事件.

现在问题:1.有更好的想法吗?2.如何通知ProcessFileServer找到的文件?它对我来说,单独创建WatchServers和ProcessServers会更方便,但在这种情况下我不知道向谁发送消息?

可能有一些类似的项目/库可用吗?

Pee*_*ger 2

在 Erlang 中创建进程非常便宜(与其他系统相比是数量级)。

因此,我建议每次出现要处理的新文件时创建一个新的 ProcessFileServer。完成后,只需使用 exit Reason 终止进程即可normal

我建议采用以下结构:

                              top_supervisor
                                      |
              +-----------------------+-------------------------+
              |                                                 |
       directory_supervisor                             processing_supervisor
               |                                         simple_one_for_one
    +----------+-----...-----+                                   |
    |          |             |                       starts children transient
    |          |             |                                   |
dir_watcher_1 dir_watcher_2 dir_watcher_n   +-------------+------+---...----+
                                            |             |                 |
                                        proc_file_1   proc_file_2       proc_file_n
Run Code Online (Sandbox Code Playgroud)

dir_watcher注意到一个新文件出现时。它使用文件路径的额外参数调用processing_supervisors函数,例如supervisor:start_child\2

应该processing_supervisor用重启策略来启动它的子进程transient

因此,如果其中一台proc_file服务器崩溃,它将重新启动,但当它们因退出原因终止时,normal它们不会重新启动。因此,您只需normal在完成后退出,并在发生其他情况时崩溃。

如果你不过分,循环轮询文件就可以了。如果系统由于此轮询而被加载,您可以调查内核通知系统(例如 FreeBSD KQUEUE 或在 MacOSX 上构建于其之上的更高级别服务),以便在目录中出现文件时向您发送消息。然而,这些服务具有复杂性,因为如果发生太多事件,它们就必须放弃(否则它们不会提高性能,而是相反)。因此,无论如何,您都必须有一个强大的轮询解决方案作为后备。

因此,不要进行过早的优化,并从轮询开始,dir_watcher在必要时添加改进(这将在服务器中隔离)。


关于评论使用什么行为作为dir_watcher进程,因为它没有使用太多gen_servers功能:

  • 仅使用部分可能性没有问题gen_servers,事实上不使用全部可能性是很常见的。在您的情况下,您只需设置一个计时器init并用于handle_info完成您的工作。其余部分gen_server只是未更改的模板。

  • 如果您稍后想要更改轮询频率等参数,可以很容易地添加到其中。

  • gen_fsm很少使用,因为它只适合非常有限的模型并且不太灵活。我仅在它确实 100% 符合要求时才使用它(但它几乎从不这样做)。

  • 如果您只想要一个简单的 Erlang 服务器,您可以使用生成函数来proc_lib获得在主管下运行的最小功能。

  • 编写更自然的 Erlang 代码并仍然具有 OTP 优势的一种有趣方法是plain_fsm,这里您具有选择性接收和灵活消息处理的优势,尤其是在处理与 OTP 的良好功能配对的协议时。

说了这么多:如果我要写 adir_watcher我只会使用 agen_server并且只使用我需要的东西。未使用的功能实际上不会花费您任何费用,而且每个人都了解它的作用。