Does Task.async_nolink start a new database connection?

Hi,

I’ve a process that batch deletes a few thousand records, which needs to be broken up to prevent the database locking up.

To do this, I’m just selecting the first 100 records, deleting them, and starting a new process which performs the same function:

def perform() do
  if_any_records_to_delete?() {
    logic_to_delete_first_100_records()
    Task.Supervisor.async_nolink(
      MyApp.BatchDeleter.Supervisor,
      fn -> perform() end
    )
  }
end

Will this setup close the connection to the DB and allow other queries to execute in-between runs, or will it maintain the same connection until all the records in question are deleted?

Thanks,
Mark

You don’t even need a new process to not block holding a connection. Unless you wrap things in Repo.transaction or Repo.checkout any function called on Repo will freshly check out a connection for execution.

You could do

def perform do
  Stream.unfold([], fn acc -> 
    if any_records_to_delete?() do
      {logic_to_delete_first_100_records(), acc}
    else
      nil 
    end
  end)
  |> Stream.run()
end
2 Likes

Thanks for the answer. I’m yet to use stream - having read through the docs I’ve one question - does it matter what I return for the acc as long as it’s not nil?

Nope. It’ll just be passed to the next iteration if it’s not nil.