【问题标题】:Single application-wide process to be accessed by child processes由子进程访问的单个应用程序范围的进程
【发布时间】:2016-03-19 00:01:08
【问题描述】:

我正在编写一个 Elixir 应用程序,其中一些访问数据库的进程将为插入的记录生成唯一标识符。

我正在使用CUID library,它可以让我通过以下方式生成一个 id:

{:ok, pid} = Cuid.start_link
Cuid.generate(pid)  # => ch72gsb320000udocl363eofy

这是我的应用程序的设置方式

  • 有一个处理请求的凤凰控制器
  • 此控制器调用我当前同步的自定义 Repo.insert 命令
  • Repo.insert 每次都会调用 Cuid.start_link 和 Cuid.generate

每次创建一个新的 Cuid 进程对我来说都是错误的,特别是考虑到 Cuid 库在其状态下维护一个计数器。

我的应用程序中的不同进程如何将Cuid.generate 发送到同一个进程?

谢谢!

【问题讨论】:

    标签: elixir erlang-otp


    【解决方案1】:

    您可以在您的应用程序中以受监督和注册的工作人员身份启动它:

    defmodule MyApp do
      use Application
    
      def start(_type, _args) do
        import Supervisor.Spec, warn: false
    
        children = [
          # Start the endpoint when the application starts
          supervisor(MyApp.Endpoint, []),
          # Start the Ecto repository
          worker(MyApp.Repo, []),
          worker(Cuid, [], [name: :cuid])
        ]
    
        opts = [strategy: :one_for_one, name: MyApp.Supervisor]
        Supervisor.start_link(children, opts)
      end
    
      ...
    end
    

    然后在您的应用程序中使用它,例如:

    cuid = Cuid.generate(:cuid)
    

    【讨论】:

    • 谢谢,我选择了这种方法。我很好奇为什么 :cuid 别名在 Phoenix 请求中可用。这种别名的范围是什么? MyApp 及其监督树下的所有内容都可以访问它吗?
    • 当您注册一个进程时,该别名可以全局访问它。因此,您在使用此模式时要小心,因为您不想在应用程序中造成瓶颈。它应该只用于真正的单例情况。您可以在大多数使用 PID 的地方替换别名,例如 GenServer.callGenServer.cast 函数。还有Process.whereis 函数等。全局注册表在分布式应用程序中还有其他一些缺点,如果您需要在真正的分布式应用程序中使用它,您可以考虑用github.com/uwiger/gproc 代替它。
    • 谢谢,这是有道理的。这是否意味着如果我有一个监督应用程序 A 和 B 的伞式应用程序,进程别名将在 A 和 B 之间共享?
    • 这取决于您如何构建和部署应用程序(请参阅EXRM)。如果您将其他应用程序添加到包含并启动应用程序 A 和 B 的保护伞,那么可以。但是,您也可以选择将 A 和 B 构建为单独的应用程序并将它们部署到不同的服务器。有时您可能希望在development 中使用单个项目的便利性,但以不同的方式部署应用程序。 Mix 处理在 development 中启动应用程序的问题,但不会出现在 prod 构建中。
    【解决方案2】:

    您可以注册您的流程:

    Process.register(pid, :cuid_process)
    

    这样,整个系统中的所有进程都可以使用它。一般在所有取正则pid的地方都可以使用注册进程所在的atom,可以试试:

    Cuid.generate(:cuid_process)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-29
      • 1970-01-01
      • 1970-01-01
      • 2017-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多