メモ帳

やったこととかちまちまと書く 需要のない記事を生成している

PhoenixでAgentを使う

Phoenixの勉強中に躓いてしまったのでメモ

Global変数らしきものが必要だったので今回はAgentを使って実装した。
他の方法としてGenServerなどがあるらしい。
elixir - A global variable in Phoenix app but not a static variable (not setting) - Stack Overflow

追記

全体で値を保持するならAgentでいいが、socketごと?に値を保持をしたければassignsを使えば簡単に実装できる
http://www.phoenixframework.org/docs/channels#section-socket-assigns
https://hexdocs.pm/phoenix/Phoenix.Socket.html#assign/3

環境

答え

lib/projectname.ex
defmodule ProjectName do
    use Application
    def start(_type, _args) do
        import Supervisor.Spec

        children = [
            supervisor(ProjectName.Repo, []),
            supervisor(ProjectName.Endpoint, []),
            worker(ProjectName.Worker, []),
        ]

        opts = [strategy: :one_for_one, name: ProjectName.Supervisor]
        Supervisor.start_link(children, opts)
    end
    ・・・
end
lib/projectname/worker.ex
defmodule ProjectName.Worker do
    def start_link do
        Agent.start_link(fn -> ["lobby"] end, name: Name)
    end
end

始めはChannel内で実装しようとしたのだが、開始元のモジュールが終了すると一緒にAgentが終了されるらしい?

注意

libディレクトリは起動時のコンパイルでしか読み込まれないようで、コマンドラインツールをつけっぱなしで再コンパイルしても更新されない。なので変更を反映させたければ一度コマンドラインツールを終了させる必要がある。