我目前正在通过Elixir in Action,我正在对我的Todo
应用程序代码进行一些重构,以便更好地掌握OTP的主要部分。在主管中有逻辑可以吗?
该应用程序使用一个数据库,它只是将数据存储在磁盘上的文件中。为确保数据库的目标文件夹存在,在数据库进程中调用File.mkdir_p!(db_folder)
。数据库进程本身使用一堆工作进程来执行从磁盘实际存储/检索数据。
我目前的章节介绍了DIY流程注册表,通过让工作人员向注册管理机构注册并让数据库进程查找使用注册表的工作人员来实施更加强大的监督树,从而双方都可以受到监督并会在失败后继续工作。
当Elixir 1.4出来时,我在补丁说明中看到了Registry
模块,所以我想我可能会重构应用程序并使用它。现在事实证明,数据库进程并不需要知道数据库用于存储数据的文件夹。所以我把mkdir_p!
叫出来,并考虑把它放在哪里。两个选项浮现在脑海中:
- 的
DatabaseWorker
- 的
DatabaseWorkerSupervisor
我个人比较倾向于第二种方法,因为整个应用程序绑定,如果用户没有访问权限反正崩溃持久性文件夹。但我不确定是否可以将逻辑放入Supervisor中。
根据情况是否将逻辑变为主管不良风格或可接受?如果风格不好,我会在哪里放置启动逻辑,如果某个进程崩溃,我不想重复该启动逻辑?
我的导师代码:
defmodule Todo.DatabaseWorkerSupervisor do
use Supervisor
def start_link(db_folder) do
Supervisor.start_link(__MODULE__, db_folder)
end
def init(db_folder) do
File.mkdir_p!(db_folder)
processes =
for worker_id <- 1..3 do
worker(Todo.DatabaseWorker, [db_folder, worker_id], id: {:dbworker, worker_id})
end
supervise(processes, strategy: :one_for_one)
end
end
我选择了这个答案,因为它直接回答了原来的问题。但是请注意,[这个答案](http://stackoverflow.com/a/43519122/4050456)如果我想'Database'是'GenServer'也是很有意义的。 –