abhay831
Delaying a Task in elixir
I am trying to show post to the first friend of a person first and other’s after making a delay of 1 mins,For that i am using genserver.
Problem is occurring that,the first friend as well as the other friends are getting the post after 1 min.
Here is my code of 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,1*60*1000)
end
end
I am starting genserver process for each post request and sending it to the first friend,
Here is the code:
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
Help me out,Thank you in advance.
Marked As Solved
hubertlepicki
I think that is totally separated problem resulting from that you are starting one job to do these two different things. I think you should start two jobs/processes, or even process per friend and give it a delay as a paremeter that they’d use to sleep on to. For the one you want to get notification immediately, you just pass 0.
If you are going to keep your own solution, change the :postSchedule message to be an actual tuple, consisting of {:postSchedule, user_id} and schedule a number of these messages in the queue, with different third send_after parameter to send those out at different dates. This way you are also de-coupling the behavior so if something fails for one user, others would not be affected.
Also Liked
OvermindDL1
For note, a while back I’ve made an efficient (at least far more efficient than lots of sleeping tasks) library to handle this:
![]()
abhay831
That’s a good work my friend,whether the taskAfter job will be async or it will make the handler to wait for the timeout.
hubertlepicki
There is one more thing you have to consider. If you do sleep tasks like that, and then you have a traditional deployment that does stop and start the Erlang VM during the process, your sleeping tasks would be silently killed and cancelled. It might be totally okay to do what you do, but in a scenario where you do multiple deployments per day it can be a show stopper as lots of these tasks would never be executed and your user experience will suffer.
So, if it’s the second case, I would advise storing the jobs somewhere. It does look like exq library already allows you to schedule delayed execution of tasks. I haven’t used it but it does appear to have enqueue_at function that wil ldo what you need: https://hexdocs.pm/exq/Exq.Enqueuer.html#enqueue_at/5
abhay831
Thank you,it worked.
OvermindDL1
Yeah Tasks are in-system only. If it needs to persist I’d recommend a database or mnesia or dets or something.
Oooo, that’s an idea… I could add a (d)ets backend to TaskAfter as an option, can someone open up an issue for that feature? ![]()
Maybe have pluggable backends via a simple behaviour, hmm…







