Erlang:创建filewatcher [英] Erlang: create filewatcher

查看:101
本文介绍了Erlang:创建filewatcher的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在Erlang中实现文件观察器功能:应该有一个进程,列出文件,如果具体的目录,并做某事,当文件出现。



我采取看看OTP。所以目前我有以下想法:
1.创建主管,将控制gen_servers(每个文件夹一个服务器)
2.为我要监视的每个文件夹创建WatchServer - gen_server。
3.创建ProcessFileServer - 应该用文件做某事的gen服务器)假设复制到不同的文件夹=



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



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



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



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

解决方案

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



因此,我建议每次出现要处理的新文件时创建一个新的ProcessFileServer。当它完成时,只是以退出原因正常终止进程。



我会建议以下结构: / p>

  top_supervisor 
|
+ ----------------------- + --------------------- ---- +
| |
directory_supervisor processing_supervisor
| simple_one_for_one
+ ---------- + -----...----- + |
| | |启动儿童短暂
| | | |
dir_watcher_1 dir_watcher_2 dir_watcher_n + ------------- + ------ + ---...---- +
| | |
proc_file_1 proc_file_2 proc_file_n

当一个 dir_watcher 通知一个新文件出现。它调用 processing_supervisor s supervisor:start_child\2 函数,其中文件的额外参数例如

processing_supervisor 应该使用 transient 重新启动策略启动其子项。



所以如果一个 proc_file 服务器正在崩溃,它将重新启动,但是当它们以退出原因终止时code>正常他们没有重新启动。所以你完成后只要退出正常的。任何其他事情都会崩溃。



如果你不过分,循环轮询轮询是好的。如果由于此轮询而导致系统加载,则可以在内核通知系统(例如FreeBSD KQUEUE或MacOSX上建立的更高级服务)上进行调查,以便在文件出现在目录中时向您发送消息。然而,这些服务具有复杂性,因为如果发生太多事件,他们有必要扔手(否则它们不会是性能改进,而是相反的)。所以你必须有一个强大的轮询解决方案作为后备。



所以不要做过早的优化,从投票开始,增加改进(这将被隔离在




关于评论使用什么行为作为 dir_watcher 进程,因为它不会使用很多 gen_servers 功能:




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


  • 如果以后要更改参数,如poll频率很容易添加到这个。


  • gen_fsm 使用得少得多,因为它只适合模式相当有限,并不是非常灵活。只有当它真的适合100%的要求时才使用它(几乎不会这样做)。


  • 在你只想要一个简单的平原Erlang的情况下服务器,您可以使用 proc_lib ,以获得在主管下运行的最小功能。


  • 一种有趣的方式来编写更自然的Erlang代码,仍然具有OTP优势是 plain_fsm ,这里您有选择性的优势接收和灵活的消息处理,特别是当处理与OTP的不错功能配对时的协议。




如果我写一个 dir_watcher ,我只需要使用一个 gen_server ,只使用我需要的东西。未使用的功能并不会给您带来任何事情,而且每个人都明白它的作用。


I have to implement file watcher functionality in Erlang: There should be a process that list files if specific directory and do something, when files appear.

I take a look at OTP. So at the moment I have following ideas: 1. Create Supervisor that will control gen_servers (one server per folder) 2. Create WatchServer - gen_server for each folder that I want to monitor. 3. Create ProcessFileServer - gen server that should do something with files )assume copy to different folder=

So First problem: WatchServer should not wait for request, it should generate one in predefined intervals.

At the moment I have created a timer in init/1 function and handle on_timer event in handle_info function.

Now questions: 1. Are there better ideas? 2. How should I inform ProcessFileServer that file found? It seams to me that it would be much more convenient create WatchServers and ProcessServers independently, but in this case I do not know to whom send message?

May be there are some similar project/libs available?

解决方案

In Erlang it is very cheap to create processes (orders of magnitudes compared to other systems).

Therefore I recommend to create a new ProcessFileServer each time a new file to process is appearing. When it is done with just terminate the process with exit reason normal.

I would suggest the following structure:

                              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

When a dir_watcher notices a new file appeared. It calls the processing_supervisors supervisor:start_child\2 function, with the extra parameter of the file pathe e.g.

The processing_supervisor should start its children with transient restart policy.

So if one of the proc_file servers is crashing it will be restarted, but when they terminate with exit reason normal they are not restarted. So you just exit normal when done and crash when whatever else happens.

If you don't overdo it, cyclic polling for files is Ok. If the system becomes loaded because of this polling you can investigate in kernel notification systems (e.g. FreeBSD KQUEUE or the higher level services building upon it on MacOSX) to send you a message when a file appears in a directory. These services however have a complexity because it is necessary for them to throw up their hands if too many events happen (otherwise they wouldn't be a performance improvement but the opposite). So you will have to have a robust polling solution as a fallback anyway.

So don't do premature optimization and start with polling, adding improvements (which would be isolated in the dir_watcher servers) when it gets necessary.


Regarding the comment what behaviour to use as dir_watcher process since it doesn't use much of gen_servers functionality:

  • There is no problem with only using part of gen_servers posibilities, in fact it is very common not to use all of it. In your case you only set up a timer in init and use handle_info to do your work. The rest of the gen_server is just the unchanged template.

  • If you later want changing parameters like poll frequency it is easy to add into this.

  • gen_fsm is much less used since it only fits a quite limited model and is not very flexible. I use it only when it really fits 100% to the requirement (which it does almost never).

  • In a case where you just want a simple plain Erlang server you can use the spawn functions in proc_lib to get just the minimal functionality to run under a supervisor.

  • A interesting way to write more natural Erlang code and still have the OTP advantages is plain_fsm, here you have the advantages of selective receive and flexible message handling needed especially when handling protocols paired with the nice features of OTP.

Having said all this: if I would write a dir_watcher I'd just use a gen_server and use only what I need. The unused functionality doesn't really cost you anything and everybody understands what it does.

这篇关于Erlang:创建filewatcher的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆