mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-02-24 14:58:35 +08:00
Fix race condition in storage test (#2068)
This commit is contained in:
parent
670f099e5e
commit
e1114d3e29
2 changed files with 13 additions and 19 deletions
|
@ -152,14 +152,6 @@ defmodule Livebook.Storage do
|
||||||
Path.join([Livebook.Config.data_path(), "livebook_config.ets"])
|
Path.join([Livebook.Config.data_path(), "livebook_config.ets"])
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
|
||||||
Synchronously awaits for all prior changes to be processed.
|
|
||||||
"""
|
|
||||||
@spec sync() :: :ok
|
|
||||||
def sync() do
|
|
||||||
GenServer.call(__MODULE__, :sync)
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def init(_opts) do
|
def init(_opts) do
|
||||||
# Make sure that this process does not terminate abruptly
|
# Make sure that this process does not terminate abruptly
|
||||||
|
@ -172,11 +164,6 @@ defmodule Livebook.Storage do
|
||||||
{:ok, %{table: table}}
|
{:ok, %{table: table}}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
|
||||||
def handle_call(:sync, _from, state) do
|
|
||||||
{:reply, :ok, state}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_call({:insert, namespace, entity_id, attributes}, _from, %{table: table} = state) do
|
def handle_call({:insert, namespace, entity_id, attributes}, _from, %{table: table} = state) do
|
||||||
keys_to_delete = Enum.map(attributes, fn {key, _val} -> key end)
|
keys_to_delete = Enum.map(attributes, fn {key, _val} -> key end)
|
||||||
|
@ -194,13 +181,11 @@ defmodule Livebook.Storage do
|
||||||
{:reply, :ok, state, {:continue, :save_to_file}}
|
{:reply, :ok, state, {:continue, :save_to_file}}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
|
||||||
def handle_call({:delete, namespace, entity_id}, _from, %{table: table} = state) do
|
def handle_call({:delete, namespace, entity_id}, _from, %{table: table} = state) do
|
||||||
:ets.delete(table, {namespace, entity_id})
|
:ets.delete(table, {namespace, entity_id})
|
||||||
{:reply, :ok, state, {:continue, :save_to_file}}
|
{:reply, :ok, state, {:continue, :save_to_file}}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
|
||||||
def handle_call({:delete_key, namespace, entity_id, key}, _from, %{table: table} = state) do
|
def handle_call({:delete_key, namespace, entity_id, key}, _from, %{table: table} = state) do
|
||||||
delete_keys(table, namespace, entity_id, [key])
|
delete_keys(table, namespace, entity_id, [key])
|
||||||
{:reply, :ok, state, {:continue, :save_to_file}}
|
{:reply, :ok, state, {:continue, :save_to_file}}
|
||||||
|
|
|
@ -105,16 +105,25 @@ defmodule Livebook.StorageTest do
|
||||||
|
|
||||||
describe "persistence" do
|
describe "persistence" do
|
||||||
defp read_table_and_lookup(entity) do
|
defp read_table_and_lookup(entity) do
|
||||||
:ok = Storage.sync()
|
Process.sleep(1)
|
||||||
|
|
||||||
{:ok, tab} =
|
{:ok, tab} =
|
||||||
Storage.config_file_path()
|
with {:error, _} <- read_table() do
|
||||||
|> String.to_charlist()
|
# :ets.tab2file is asynchronous and may occasionally take
|
||||||
|> :ets.file2tab()
|
# longer, so we retry once
|
||||||
|
Process.sleep(100)
|
||||||
|
read_table()
|
||||||
|
end
|
||||||
|
|
||||||
:ets.lookup(tab, {:persistence, entity})
|
:ets.lookup(tab, {:persistence, entity})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp read_table() do
|
||||||
|
Storage.config_file_path()
|
||||||
|
|> String.to_charlist()
|
||||||
|
|> :ets.file2tab()
|
||||||
|
end
|
||||||
|
|
||||||
test "insert triggers saving to file" do
|
test "insert triggers saving to file" do
|
||||||
:ok = Storage.insert(:persistence, "insert", key: "val")
|
:ok = Storage.insert(:persistence, "insert", key: "val")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue