washeku

washeku

Background Task with autokilling itself and repeated action each N minutes

I want to create a bunch of background jobs dynamically. A job should run at most N minutes, strictly, and then kill itself.
It’ll check a state of some console application once a minute and if a state returns true, a job writes data into a database and kills itself ahead right away, otherwise it’ll keep checking for N minutes at most.

I’m looking for pointers of how to achieve that. I want a simple solution.
Should I use Task? If so, how should I specify the N minutes over the course of which it’ll be alive?
How can I make it to poll a state of an application once a minute?

Most Liked

josevalim

josevalim

Creator of Elixir

For some yes, for others no. :slight_smile: We need to be careful with those sentences because they may discourage conversation. If something is trivial and someone doesn’t understand it, they may think it is their fault after all.

In any case, you are right, so thanks for pointing to the right direction. @washeku please see the following example as a starting point: How can I schedule code to run every few hours in Elixir or Phoenix framework? - Stack Overflow

if it is not clear, please ask! I am sure @OvermindDL1, myself and others will be happy to help!

OvermindDL1

OvermindDL1

All fairly trivial with a GenServer, you can even send back yourself a message with a timeout (it only arrives if no other messages have arrived) or always in some-odd minutes regardless of any other messages (send_after). :slight_smile:

You can do it with Task by using send_after though, but a GenServer really sounds best for this task as it does not sound like a one-off.

OvermindDL1

OvermindDL1

With send_after, something like:

def init(args) do
  killSelfTime = args.death_minutes * 1000 * 60 # send_after wants milliseconds
  Process.send_after(self(), :kill_self, killSelfTime)
  state = encodeWhateverYouWantToDoHere(args)
  {:ok, state}
end

def handle_info(:kill_self, state) do
  cleanup()
  {:stop, :normal}
end

defp cleanup() do
  # If you need to do something else like cancel some pending function or un-register with
  # another server or something
end
sasajuric

sasajuric

Author of Elixir In Action

+1

Two processes would be my choice here as well. One does the job, another watches over the job runner and terminates it if it doesn’t finish in the given timeframe. That should properly take care of the case where the job is blocking for a long time (possibly forever).

Arguably the simplest solution could be based on a task:

poll_loop = Task.async(fn ->
  # simulation of a poll loop
  :timer.sleep(:rand.uniform(:timer.seconds(2)))
end)

# waiting for at most 1 second for the loop to finish
case Task.yield(poll_loop, :timer.seconds(1)) do
  {:ok, _} -> IO.puts "loop finished."
  nil ->
    IO.puts "timeout: killing the loop runner."
    Task.shutdown(poll_loop, :brutal_kill)
end

Probably the simplest way to implement the poll loop would be through recursion:

def poll_loop() do
  case poll() do
    :ok -> :ok
    :error ->
      :timer.sleep(:timer.seconds(1))
      poll_loop()
  end
end
idi527

idi527

I think handle_info callback should return {:stop, :normal, state}.

Where Next?

Popular in Questions Top

joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New

Other popular topics Top

quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

We're in Beta

About us Mission Statement