代码之家  ›  专栏  ›  技术社区  ›  t56k

如何使GenServer进程可用于我的整个应用程序?

  •  1
  • t56k  · 技术社区  · 7 年前

    我使用GenServer作为排队系统。如何让整个应用程序都可以访问相同的过程?

    application.ex

    children = [
      supervisor(Prefect, [], name: PrefectQueue)
    ]
    

    Prefect 模块是发电机服务器:

    defmodule Prefect do
      use GenServer
      alias Prefect.Document
    
      # client
      def start_link() do
        GenServer.start_link(__MODULE__, [])
      end
    
      def add(pid, item) do
        GenServer.cast(pid, item)
      end
    
      # server
      def handle_cast(item, list) do
        updated_list = [item | list]
        {:noreply, updated_list}
      end
    end
    

    不过,我似乎无法在控制器中访问它:

    defmodule PrefectWeb.DocumentController do
      use PrefectWeb, :controller
    
      def create(conn, params) do
        Prefect.add(PrefectQueue, params["id"])
        conn
        |> send_resp(200, "Queued #{Prefect.view(PrefectQueue)}")
      end
    end
    

    [info] POST /api/documents
    [debug] Processing with PrefectWeb.DocumentController.create/2
      Parameters: %{"id" => "1"}
      Pipelines: [:api]
    [error] #PID<0.349.0> running PrefectWeb.Endpoint terminated
    Server: 0.0.0.0:4000 (http)
    Request: POST /api/documents
    ** (exit) exited in: GenServer.call(Prefect.Queue, :view, 5000)
        ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Phillipp    7 年前

    您必须在GenServer本身中命名进程,而不是通过supervisor childs列表。尝试:

    defmodule Prefect do
      use GenServer
      alias Prefect.Document
    
      # client
      def start_link() do
        GenServer.start_link(__MODULE__, [], name: __MODULE__)
      end
    
      def add(pid, item) do
        GenServer.cast(pid, item)
      end
    
      # server
      def handle_cast(item, list) do
        updated_list = [item | list]
        {:noreply, updated_list}
      end
    end
    

    Prefect.view(Prefect) .