From c4f6cbab20b0b1d08755073d93365e5bd00dc755 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Tue, 6 Nov 2018 11:57:09 +0100 Subject: Shard deletion ; update README and TODO --- shard/lib/app/chat.ex | 5 +++++ shard/lib/app/directory.ex | 4 ++++ shard/lib/app/file.ex | 6 ++++++ shard/lib/app/identity.ex | 4 ++++ shard/lib/app/pagestore.ex | 16 ++++++++++++---- shard/lib/cli/cli.ex | 10 +++++++++- shard/lib/manager.ex | 31 ++++++++++++++++++++++++++++++- 7 files changed, 70 insertions(+), 6 deletions(-) (limited to 'shard/lib') diff --git a/shard/lib/app/chat.ex b/shard/lib/app/chat.ex index 2795153..ff0c97d 100644 --- a/shard/lib/app/chat.ex +++ b/shard/lib/app/chat.ex @@ -131,6 +131,11 @@ defmodule SApp.Chat do {:reply, state.manifest, state} end + def handle_call(:delete_shard, _from, state) do + GenServer.call(state.store, :delete_store) + {:stop, :normal, :ok, state} + end + def handle_call({:read_history, top_bound, num}, _from, state) do ret = MST.last(state.mst, top_bound, num) {:reply, ret, state} diff --git a/shard/lib/app/directory.ex b/shard/lib/app/directory.ex index e9482f7..cbea8c3 100644 --- a/shard/lib/app/directory.ex +++ b/shard/lib/app/directory.ex @@ -64,6 +64,10 @@ defmodule SApp.Directory do {:reply, state.manifest, state} end + def handle_call(:delete_shard, _from, state) do + {:stop, :normal, :ok, state} + end + def handle_call(:get_items, _from, state) do {:reply, SData.SignRev.get(state.items), state} end diff --git a/shard/lib/app/file.ex b/shard/lib/app/file.ex index ce28beb..e2a9798 100644 --- a/shard/lib/app/file.ex +++ b/shard/lib/app/file.ex @@ -84,6 +84,12 @@ defmodule SApp.File do {:reply, state.manifest, state} end + def handle_call(:delete_shard, _from, state) do + GenServer.call(state.store, :delete_store) + File.rm(state.path) + {:stop, :normal, :ok, state} + end + def handle_call(:get_info, _from, state) do reply = cond do state.info != nil and GenServer.call(state.store, {:have_rec, state.info.merkle_root}) -> diff --git a/shard/lib/app/identity.ex b/shard/lib/app/identity.ex index 59a4b90..78abbe7 100644 --- a/shard/lib/app/identity.ex +++ b/shard/lib/app/identity.ex @@ -65,6 +65,10 @@ defmodule SApp.Identity do {:reply, state.manifest, state} end + def handle_call(:delete_shard, _from, state) do + {:stop, :normal, :ok, state} + end + def handle_call(:get_info, _from, state) do {:reply, SData.SignRev.get(state.state), state} end diff --git a/shard/lib/app/pagestore.ex b/shard/lib/app/pagestore.ex index 5165b84..3cda51d 100644 --- a/shard/lib/app/pagestore.ex +++ b/shard/lib/app/pagestore.ex @@ -25,7 +25,7 @@ defmodule SApp.PageStore do @max_failures 4 # Maximum of peers that reply not_found before we abandon defmodule State do - defstruct [:shard_id, :path, :netgroup, :store, :reqs, :retries] + defstruct [:shard_id, :path, :netgroup, :store, :reqs, :retries, :store_path] end @@ -36,15 +36,21 @@ defmodule SApp.PageStore do def init([shard_id, path, netgroup]) do Shard.Manager.dispatch_to(shard_id, path, self()) - store_path = [Application.get_env(:shard, :data_path), "#{shard_id|>Base.encode16}.#{path}"] |> Path.join |> String.to_atom - {:ok, store} = :dets.open_file store_path, [type: :set] + store_path = [Application.get_env(:shard, :data_path), "#{shard_id|>Base.encode16}.#{path}"] |> Path.join + {:ok, store} = :dets.open_file(String.to_atom(store_path), [type: :set]) Process.send_after(self(), :clean_cache, 1000) - {:ok, %State{shard_id: shard_id, path: path, netgroup: netgroup, store: store, reqs: %{}, retries: %{}}} + {:ok, %State{shard_id: shard_id, path: path, netgroup: netgroup, store: store, reqs: %{}, retries: %{}, store_path: store_path}} end + def handle_call(:delete_store, _from, state) do + :dets.close state.store + File.rm state.store_path + {:stop, :normal, :ok, state} + end + def handle_call({:get, key, prefer_ask}, from, state) do case :dets.lookup state.store, key do [{_, _, bin}] -> @@ -84,9 +90,11 @@ defmodule SApp.PageStore do case :dets.lookup state.store, hash do [] -> :dets.insert state.store, {hash, {:cached, System.os_time(:seconds) + @cache_ttl}, bin} + :dets.sync state.store nil [{_, why}] -> :dets.insert state.store, {hash, why, bin} + :dets.sync state.store why [{_, _, _}] -> nil diff --git a/shard/lib/cli/cli.ex b/shard/lib/cli/cli.ex index 380282d..54b882f 100644 --- a/shard/lib/cli/cli.ex +++ b/shard/lib/cli/cli.ex @@ -94,8 +94,16 @@ defmodule SCLI do end defp handle_command(state, ["list"]) do - IO.puts "List of known channels:" + IO.puts "Private conversations:" + for {_chid, %SApp.Chat.PrivChat.Manifest{pk_list: pk_list}, _} <- Shard.Manager.list_shards do + pk_list + |> Enum.filter(&(&1 != state.pk)) + |> Enum.map(fn pk -> "#{SApp.Identity.get_nick pk} #{Shard.Keys.pk_display pk}" end) + |> Enum.join(", ") + |> IO.puts + end + IO.puts "Public channels we are connected to:" for {_chid, %SApp.Chat.Manifest{channel: chan}, _} <- Shard.Manager.list_shards do IO.puts "##{chan}" end diff --git a/shard/lib/manager.ex b/shard/lib/manager.ex index c178e2f..c3897a3 100644 --- a/shard/lib/manager.ex +++ b/shard/lib/manager.ex @@ -82,6 +82,27 @@ defmodule Shard.Manager do {:reply, pid, state} end + def handle_call({:delete, shard_id}, _from, state) do + case :dets.lookup(@shard_db, shard_id) do + [] -> + {:reply, {:error, :not_found}, state} + [{^shard_id, manifest, {:cached, _}, _}] -> + pid = case :ets.lookup(:shard_procs, {shard_id, nil}) do + [] -> + {:ok, pid} = apply(Shard.Manifest.module(manifest), :start_link, [manifest]) + pid + [{{^shard_id, nil}, pid}] -> + :ets.delete(:shard_procs, {shard_id, nil}) + pid + end + GenServer.call(pid, :delete_shard) + :dets.delete(@shard_db, shard_id) + {:reply, :ok, state} + [{^shard_id, _, _, _}] -> + {:reply, {:error, :pinned}, state} + end + end + def handle_cast({:dispatch_to, shard_id, path, pid}, state) do :ets.insert(:shard_procs, { {shard_id, path}, pid }) state = Map.put(state, pid, {shard_id, path}) @@ -105,6 +126,7 @@ defmodule Shard.Manager do case :dets.lookup(@shard_db, shard_id) do [{^shard_id, manifest, why_have_it, _old_state}] -> :dets.insert(@shard_db, {shard_id, manifest, why_have_it, shst}) + :dets.sync(@shard_db) end {:noreply, state} end @@ -169,7 +191,7 @@ defmodule Shard.Manager do for [id] <- shards do case :ets.lookup(:shard_procs, {id, nil}) do [{{^id, nil}, pid}] -> - GenServer.cast(pid, :delete_shard) + GenServer.call(pid, :delete_shard) _ -> nil end :dets.delete(@shard_db, id) @@ -365,6 +387,13 @@ defmodule Shard.Manager do end end + @doc""" + Delete a shard + """ + def delete(shard_id) do + GenServer.call(__MODULE__, {:delete, shard_id}) + end + @doc""" Return the list of all shards. Returns a list of tuples: -- cgit v1.2.3