灵药延迟任务中的GenServer



我试图在延迟 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 

我正在为每个帖子请求启动一个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

帮我,提前谢谢你。

注意:我知道这是一个相当古老的问题,但也许其他人也有类似的问题并最终来到这里。

我认为您想首先触发一个操作,然后在一分钟后触发另一个操作。代码的问题在于,您在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

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

最新更新