Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 主管有逻辑可以吗?_Elixir_Otp - Fatal编程技术网

Elixir 主管有逻辑可以吗?

Elixir 主管有逻辑可以吗?,elixir,otp,Elixir,Otp,我目前正在使用Elixir,我正在对我的Todo应用程序代码进行重构,以便更好地掌握OTP的主要部分 应用程序使用的数据库只是将数据存储在磁盘上的文件中。要确保数据库的目标文件夹存在,File.mkdir\p!(db_folder)在数据库进程内调用。数据库进程本身使用一组工作进程来执行实际的磁盘数据存储/检索 我目前所在的章节介绍了一个DIY流程注册表,通过让工作人员将自己注册到注册表,并让数据库流程查找使用注册表的工作人员,实现了一个更健壮的监督树,这样双方都可以受到监督,并且在失败后仍然可

我目前正在使用Elixir,我正在对我的
Todo
应用程序代码进行重构,以便更好地掌握OTP的主要部分

应用程序使用的数据库只是将数据存储在磁盘上的文件中。要确保数据库的目标文件夹存在,
File.mkdir\p!(db_folder)
在数据库进程内调用。数据库进程本身使用一组工作进程来执行实际的磁盘数据存储/检索

我目前所在的章节介绍了一个DIY流程注册表,通过让工作人员将自己注册到注册表,并让数据库流程查找使用注册表的工作人员,实现了一个更健壮的监督树,这样双方都可以受到监督,并且在失败后仍然可以工作

当Elixir1.4面世时,我在补丁说明中读到了
注册表
模块,所以我想我可能会重构应用程序并使用它。现在,事实证明,数据库进程实际上不必知道数据库用于存储数据的文件夹。所以我拿了
mkdir\p调用该模块并考虑将其放置在何处。我想到两个选择:

  • DatabaseWorker
  • DatabaseWorkerSupervisor
  • 我个人更喜欢第二种方法,因为如果用户没有访问持久性文件夹的权限,整个应用程序肯定会崩溃。但我不太确定把逻辑放在一个主管身上是否合适

    根据具体情况,将逻辑放在主管的风格中是错误的还是可以接受的?如果是糟糕的风格,我应该把启动逻辑放在哪里?如果进程崩溃,我不想重复启动逻辑


    我的主管代码:

    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
    
    defmodule Todo.databaseworker supervisor do
    使用主管
    def start_链接(db_文件夹)do
    Supervisor.start\u链接(\u模块\u,db\u文件夹)
    终止
    def init(db_文件夹)do
    File.mkdir_p!(db_文件夹)
    进程=
    
    对于worker_id,我不希望将逻辑放在主管中。如果您开始在管理器中添加逻辑,您无法通过查看管理树来解释崩溃/重启的原因。相反,我将建议以下监督树:

    如果将文件夹创建放在DB gen服务器的
    init
    中,DBSupervisor将等待
    init
    返回,然后再转到其他子文件夹。因此,如果文件夹创建失败,则监管树的其余部分甚至不会生成。此外,如果DBSupervisor策略是
    :rest\u for_all
    ,则DB gen服务器中的任何故障都将重新启动监控树的其余部分

    我知道这个答案似乎有些过分,但如果重点放在纠正和学习上,我认为这是正确的方向


    一个重要的提示。正如您所说的,有了注册中心,您就不需要DB gen服务器来将任务从客户端传递给工作者,您是对的!尽管建议的监控树看起来与注册表之前的监控树相似,但您现在应该只调用函数(可以在DB模块中实现)来查询注册表,并将任务直接从客户端进程传递给工作进程。

    我不希望将逻辑放在监控树中。如果您开始在管理器中添加逻辑,您无法通过查看管理树来解释崩溃/重启的原因。相反,我将建议以下监督树:

    如果将文件夹创建放在DB gen服务器的
    init
    中,DBSupervisor将等待
    init
    返回,然后再转到其他子文件夹。因此,如果文件夹创建失败,则监管树的其余部分甚至不会生成。此外,如果DBSupervisor策略是
    :rest\u for_all
    ,则DB gen服务器中的任何故障都将重新启动监控树的其余部分

    我知道这个答案似乎有些过分,但如果重点放在纠正和学习上,我认为这是正确的方向

    一个重要的提示。正如您所说的,有了注册中心,您就不需要DB gen服务器来将任务从客户端传递给工作者,您是对的!尽管建议的监控树看起来与注册表之前的监控树相似,但现在您应该只调用函数(可以在DB模块中实现)来查询注册表并将任务直接从客户端进程传递给工作进程

    如果进程崩溃,我不想重复的启动逻辑应该放在哪里

    从supervisor
    init
    调用这个似乎是合乎逻辑的。 特别是如果你不想重复的话

    也许代码可以在另一个模块中定义,但是从supervisor init调用它是有意义的,如果初始化失败,让supervisor崩溃

    如果进程崩溃,我不想重复的启动逻辑应该放在哪里

    从supervisor
    init
    调用这个似乎是合乎逻辑的。 特别是如果你不想重复的话


    也许代码可以在另一个模块中定义,但从supervisor init调用它是有意义的,如果初始化失败,让supervisor崩溃。

    Sasa将在几页之后从
    数据库
    模块中删除GenServer行为,因为它不再保持状态,只执行注册表查找和委派。在这种情况下,您会将文件夹创建放在哪里?我认为我的建议仍然有效,即使DB gen服务器只负责初始化时的文件夹创建。同样,这是一种过分的做法,但其目的是学习适当的OTP开发。但也许我错了。让我们看看其他建议……Sasa在几页之后从
    数据库
    模块中删除GenServer行为,因为它不再保持状态,而只是执行注册表