erlang 延迟任务中的GenServer

jvlzgdj9  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(151)

我试图先向一个人的第一个朋友显示一个帖子,然后在延迟1分钟后向其他人的朋友显示。为此,我使用GenServer。
问题是,第一个朋友以及其他朋友在1分钟后收到帖子。
下面是我的GenServer代码:

defmodule Phoenix.SchedulePost do
  use GenServer
  
  def start_link(state) do
    GenServer.start_link(__MODULE__, state)
  end
  
  def init(state) do
    schedule_post(state)
    {:ok, state}
  end
  
  # handling looby
  def handle_info(:postSchedule, state) do
    #sending posts to others
    {:noreply, state}
  end
  
  # scheduling a task
  defp schedule_post(state) do
    IO.puts "scheduling the task"
    Process.send_after(self(), :postSchedule, 60*1000)
  end
end

我为每个post请求启动一个GenServer进程,并将其发送给第一个朋友。

def handle_in("post:toFrstFrnd", %{"friendId"=>friendId,"body" => body}, socket) do
  newSocket = PhoenixWeb.SocketBucket.get_socket(friendId)
  if  newSocket != nil do
    push newSocket, "post:toFrstFrnd", %{"friendId": friendId,"body": body}
  end
  Phoenix.SchedulePost.start_link(postId)
  {:noreply, socket}
end

帮我个忙,先谢谢你了。

7kjnsjlb

7kjnsjlb1#

**注:**我知道这是一个相当古老的问题,但也许其他人也有类似的问题,并在这里结束。

我认为您希望首先触发一个操作,然后在一分钟后触发另一个操作。您的代码的问题是,您在init方法中调用了schedule_post方法,但它在一分钟内什么也不做。一分钟后,您向进程本身发送了一条消息,于是handle_info方法接管了它。但现在对于初始操作来说已经太晚了。
下面是一个示例:

defmodule Phoenix.SchedulePost do
  use GenServer

  def start_link(state \\ []) do
    GenServer.start_link(__MODULE__, state)
  end

  def init(state) do
    send(self(), :first_action)
    {:ok, state}
  end

  def handle_info(:first_action, state) do
    IO.puts("Called immediately")
    # Do something here...

    Process.send_after(self(), :second_action, 60 * 1000)
    {:noreply, state}
  end

  def handle_info(:second_action, state) do
    IO.puts "Called after 1 min"
    # Do something here...

    {:noreply, state}
  end
end

但请记住,即使在第二个操作完成后,进程仍将继续存在。它不会自动终止,您必须注意这一点。

相关问题