2016-03-18 60 views
2

我寫的藥劑應用程序,其中一些訪問數據庫將產生唯一標識符的是還會插入記錄的過程。單應用範圍的進程處理

我使用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同一進程?

謝謝!

回答

5

你可以啓動它在你的應用程序中的監督和登記的工作人員:

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) 
+0

謝謝,我選擇了這種方式。我很好奇爲什麼在菲尼克斯請求中可以使用cuid別名。這種別名的範圍是什麼? MyApp及其監督樹下的所有內容都可以訪問嗎? –

+0

當你註冊一個進程時,它可以被該別名全局訪問。因此,您在使用此模式時要小心,因爲您不想在應用程序中創建瓶頸。它只能用於真正的單身情況。你可以用別名替代大多數你會使用PID的地方,比如'GenServer.call'和'GenServer.cast'函數。另外,'Process.whereis'功能等全局註冊表有一些其他方面的不足在分佈式應用程序,如果你需要在一個真正的分佈式應用程序來使用它,你可以代替考慮https://github.com/uwiger/gproc它。 –

+0

謝謝,這是有道理的。這是否意味着如果我有一個監視應用程序A和B的傘式應用程序,那麼進程別名將在A和B之間共享? –

2

可以註冊的過程:

Process.register(pid, :cuid_process) 

這種方式使您能在整個系統中的所有進程。通常你可以使用在其過程是在採取常規PID所有地方註冊的原子,所以你可以嘗試:

Cuid.generate(:cuid_process)