Elixir - 库依赖项之间的死锁

时间:2018-03-20 20:39:42

标签: elixir phoenix-framework

上下文

我正在构建自己的代码库,用于处理ElasticSearch,使用Tirexs包。这是我第一次深入研究宏,依赖,使用,导入以及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

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

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

第一个依赖项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

其他依赖项也指模块和结构,所以我认为死锁与此有关。但我迷失了该怎么做。

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

提前致谢!

2 个答案:

答案 0 :(得分:4)

你有循环依赖。

Document -> Document.Builder -> Document.AuxiliarBuilder -> Document

一般来说,您应该避免使用子模块(Document.BuilderDocument.AuxiliarBuilder)来调用其父模块(Document)。听起来你需要从Document中提取这些函数并将它们放在别处。

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

答案 1 :(得分:0)

显然循环依赖是因为结构的定义,即%Document,并且与模块名称混淆。

将结构定义移动到它自己的单独文件中(前几行here是提示),并将模块名称从Document更改为Data.Document%Data.Document )足以解决所有循环依赖。