aboutsummaryrefslogtreecommitdiff
path: root/shard
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2018-11-06 11:57:09 +0100
committerAlex Auvolat <alex@adnab.me>2018-11-06 11:57:09 +0100
commitc4f6cbab20b0b1d08755073d93365e5bd00dc755 (patch)
tree384dd05c59a810d503790a2af1b5c49e1aed5ccf /shard
parent0e5b82f3348508eb7f4291a08722522a49edd752 (diff)
downloadshard-c4f6cbab20b0b1d08755073d93365e5bd00dc755.tar.gz
shard-c4f6cbab20b0b1d08755073d93365e5bd00dc755.zip
Shard deletion ; update README and TODO
Diffstat (limited to 'shard')
-rw-r--r--shard/lib/app/chat.ex5
-rw-r--r--shard/lib/app/directory.ex4
-rw-r--r--shard/lib/app/file.ex6
-rw-r--r--shard/lib/app/identity.ex4
-rw-r--r--shard/lib/app/pagestore.ex16
-rw-r--r--shard/lib/cli/cli.ex10
-rw-r--r--shard/lib/manager.ex31
7 files changed, 70 insertions, 6 deletions
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)
@@ -366,6 +388,13 @@ defmodule Shard.Manager do
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:
{id, manifest, why_have_it}