Elixir - 库依赖之间的死锁

Seb*_*nso 3 elixir phoenix-framework

上下文

我正在使用 Tirexs 包构建自己的用于处理 ElasticSearch 的代码库。这是我第一次深入研究宏、依赖项、使用、导入和 Elixir 提供的其他几个最高级的功能。

为此,我定义了一个Document大致如下所示的结构,( /lib/data/document.ex)

defmodule Document do
  use Document.ORM
  import Document.Builder, only: [build_document: 2]
  import Document.Builder.Validations, only: [is_document_valid?: 1, collect_errors: 1]

  defstruct [valid?: false, errors: nil, fields: %{}]

  def something do
    # uses imported functions from Document.Builder and Documen.Builder.Validations
  end
end
Run Code Online (Sandbox Code Playgroud)

然后Document模块使用模块中的其他几个Document.ORM似乎不是错误原因的函数。

问题

我的错误如下

Compilation failed because of a deadlock between files.
dataobj_1          | The following files depended on the following modules:
dataobj_1          | 
dataobj_1          |   web/controllers/document_controller.ex => Document
dataobj_1          |             lib/data/document/builder.ex => Document.Builder.AuxiliarBuilder
dataobj_1          |                     lib/data/document.ex => Document.Builder
dataobj_1          |      lib/data/document/orm/bulk/utils.ex => Document
dataobj_1          |    lib/data/document/builder/auxiliar.ex => Document
Run Code Online (Sandbox Code Playgroud)

有一个我不知道如何处理的僵局,我确定我做错了什么。

第一个依赖项document_controller出现(我认为)是因为它在不同的地方都引用了模块Document%Document结构:

defmodule Data.DocumentController do
  use Data.Web, :controller

  def create(conn, %{"document" => document_params}) do
      {:ok, doc} = document_params 
        |> Document.new
      case Document.save(doc) do
        {:ok, record} ->
          conn
          |> put_status(201)
          |> render(Data.DocumentView, "document.json", payload: Document.find(record._id))
        {:error, map_of_errors} ->
          conn
          |> put_status(422)
          |> render(Data.ErrorView, "422.json", errors: map_of_errors)
      end
  end
  def update(conn, %{"id" => id, "document" => document}) do
    case Document.update(id, document) do
      %Document{valid?: false, errors: errors} ->
        conn
        |> put_status(422)
        |> render(Data.ErrorView, "422.json", errors: errors)
      docset ->
        conn
        |> put_status(200)
        |> render(Data.DocumentView, "update.json", payload: docset)
    end
  end
Run Code Online (Sandbox Code Playgroud)

其他依赖项也同时引用模块和结构,所以我认为死锁与此有关。但我不知道该怎么做。

如果有必要,我可以分享更多代码,但要开始这个问题,我认为就足够了。

提前致谢!

Jus*_*ood 5

你有循环依赖。

Document -> Document.Builder -> Document.AuxiliarBuilder -> Document
Run Code Online (Sandbox Code Playgroud)

一般来说,您应该避免子模块 ( Document.Builder, Document.AuxiliarBuilder) 调用它们的父模块( Document)。听起来您需要从中提取这些功能Document并将它们放在其他地方。

注意:Elixir 实际上没有父模块和子模块的概念。我只是在这里使用这些词,因为这就是我的想法。