Erlang:创建filewatcher [英] Erlang: create filewatcher
问题描述
我采取看看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_supervisor
s 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 ininit
and usehandle_info
to do your work. The rest of thegen_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屋!