Inconsistent state when saving to DETS table

I am having mixed results with DETS on my tests. They will pass sometimes and others they wont. It seems like maybe the record hasn’t been written fast enough and is causing my tests to fail. (My tests are checking that a function has mutated the value inside of a DETS table.) Does that sound like it could be happening? and if so, is there a way around it? like a way to ensure the update has been written before moving on?

some of the code:

def last_hash do
    {:ok, table} = last_hash_table |> :dets.open_file([type: :set])
    ret = :dets.lookup(table, :last_hash) |> Keyword.get(:last_hash, "AAAA")
    :dets.close(table)
    ret
  end

  defp last_hash(str) do
    {:ok, table} = last_hash_table |> :dets.open_file([type: :set])
    ret = :dets.insert(table, {:last_hash, str})
    :dets.close(table)
    ret
  end

Thanks!

DETS tables are designed to be “owned” by a single process. It should open the file on init, and keep the table open. Look at :auto_save (http://erlang.org/doc/man/dets.html#open_file-2) to control how often items are flushed to disk.

Instead of directly opening the DETS table in your tests, add functions to the owner to retrieve the information for you. Something like:

def last_hash() do
    GenServer.call(@server_name,:read_last_hash)
end
...
def handle_call(:read_last_hash,_from,state=%{table: table}) do
   ret = :dets.lookup(table, :last_hash) |> Keyword.get(:last_hash, "AAAA")
   {:reply, ret, state}
end
1 Like