使用 OTP 从进程中检索文本

问题描述

我是 Elixir/Phoenix 的新手,我正在阅读一本“Phoenix 编程”一书,我正在尝试从 Wolfram 中检索我在控制台中输入的问题的答案。但是,我得到一个响应,一个进程不活跃,因此是空的。我做错了什么?

控制台:

iex(20)> Rumbl.InfoSys.compute("what is firebird?")      
[
  %Task{
    owner: #PID<0.399.0>,pid: #PID<0.477.0>,ref: #Reference<0.4114193905.3572760578.72489>
  }
]
iex(21)> flush()
{#Reference<0.4114193905.3572760578.72368>,[]}
{:DOWN,#Reference<0.4114193905.3572760578.72368>,:process,#PID<0.438.0>,:normal}
{#Reference<0.4114193905.3572760578.72391>,#Reference<0.4114193905.3572760578.72391>,#PID<0.451.0>,:normal}
{#Reference<0.4114193905.3572760578.72489>,#Reference<0.4114193905.3572760578.72489>,#PID<0.477.0>,:normal}
:ok

这是我的 cache.ex

defmodule Rumbl.Cache do
  use GenServer
  @clear_interval :timer.seconds(60)

  def put(name \\ __MODULE__,key,value) do
    true = :ets.insert(tab_name(name),{key,value})
    :ok
  end

  def fetch(name \\ __MODULE__,key) do
    {:ok,:ets.lookup_element(tab_name(name),2)}
  rescue
    ArgumentError -> :error
  end

  def start_link(opts) do
    opts = Keyword.put_new(opts,:name,__MODULE__)
    GenServer.start_link(__MODULE__,opts,name: opts[:name])
  end

  def init(opts) do
    state = %{
      interval: opts[:clear_interval] || @clear_interval,timer: nil,table: new_table(opts[:name])
    }

    {:ok,schedule_clear(state)}
  end

  def handle_info(:clear,state) do
    :ets.delete_all_objects(state.table)
    {:noreply,schedule_clear(state)}
  end

  defp schedule_clear(state) do
    %{state | timer: Process.send_after(self(),:clear,state.interval)}
  end

  defp new_table(name) do
    name
    |> tab_name()
    |> :ets.new([
       :set,:named_table,:public,read_concurrency: true,write_concurrency: true])
  end

  defp tab_name(name),do: :"#{name}_cache"
end

我的 wolfram.ex

  import SweetXml
  alias Rumbl.InfoSys.Result
  @behaviour Rumbl.Backend
  @base "http://wolframalpha.com/v2/query"

  @impl true
  def name,do: "wolfram"

  @impl true
  def compute(query_str,_opts) do
    query_str
    |> fetch_xml()
    |> xpath(~x"/queryresult/pod[contains(@title,'Result') or
                                contains(@title,'Definitions')]
                            /subpod/plaintext/text()")
    |> build_results()
  end

  defp build_results(nil),do: []

  defp build_results(answer) do
    [%Result{backend: __MODULE__,score: 95,text: to_string(answer)}]
  end

  defp fetch_xml(query) do
    {:ok,{_,_,body}} = :httpc.request(String.to_charlist(url(query)))

    body
  end

  defp url(input) do
    "#{@base}?" <>
    URI.encode_query(appid: id(),input: input,format: "plaintext")
  end

  defp id,do: Application.fetch_env!(:rumbl,:wolfram)[:app_id]
end

info_sys.ex

  @backends [Rumbl.Wolfram]
  defmodule Result do
    defstruct score: 0,text: nil,backend: nil
  end

  def compute(query,opts \\ []) do
    opts = Keyword.put_new(opts,:limit,10)
    backends = opts[:backends] || @backends

    backends
    |> Enum.map(&async_query(&1,query,opts))
  end

  defp async_query(backend,opts) do
    Task.Supervisor.async_nolink(Rumbl.TaskSupervisor,backend,:compute,[query,opts],shutdown: :brutal_kill
      )
  end
end

后端.ex

defmodule Rumbl.Backend do
  @callback name() :: String.t()
  @callback compute(query :: String.t(),opts :: Keyword.t()) ::
  [%Rumbl.InfoSys.Result{}]
  end

有没有人知道我做错了什么?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...