aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2018-11-06 15:22:30 +0100
committerAlex Auvolat <alex@adnab.me>2018-11-06 15:22:30 +0100
commitf25929e45cfbe25bb7401c9af126d353e1eaef86 (patch)
treeba789ca3de36b777d2c7d2ac500721f38732133b
parent2973cf99c5b677c71717d916f83212bc2e6b36dc (diff)
downloadshard-f25929e45cfbe25bb7401c9af126d353e1eaef86.tar.gz
shard-f25929e45cfbe25bb7401c9af126d353e1eaef86.zip
Cleanup ; make file download from CLI doable
-rw-r--r--README.md1
-rw-r--r--shard/lib/app/chat.ex2
-rw-r--r--shard/lib/app/file.ex13
-rw-r--r--shard/lib/app/pagestore.ex7
-rw-r--r--shard/lib/cli/cli.ex36
-rw-r--r--shard/lib/manager.ex7
6 files changed, 56 insertions, 10 deletions
diff --git a/README.md b/README.md
index db52b04..265fea6 100644
--- a/README.md
+++ b/README.md
@@ -222,4 +222,5 @@ This CLI supports a few basic commands:
- `/send_file path`: make file available on the network and send link to current chat room.
**WARNING: all files are publicly available for now, even if they are sent in a private chat room.**
- `/shards`: return the list of all shards on the system
+- `/info [file_shard_uri]`: shows progress of a file download. Starts download if not already started.
- `/quit`: return to iex prompt
diff --git a/shard/lib/app/chat.ex b/shard/lib/app/chat.ex
index b046fc3..8a72d48 100644
--- a/shard/lib/app/chat.ex
+++ b/shard/lib/app/chat.ex
@@ -130,7 +130,7 @@ defmodule SApp.Chat do
end
def handle_call(:delete_shard, _from, state) do
- GenServer.call(state.store, :delete_store)
+ SApp.PageStore.delete_store(state.store)
{:stop, :normal, :ok, state}
end
diff --git a/shard/lib/app/file.ex b/shard/lib/app/file.ex
index 0e07cc3..7f03e1f 100644
--- a/shard/lib/app/file.ex
+++ b/shard/lib/app/file.ex
@@ -85,7 +85,7 @@ defmodule SApp.File do
infobin ->
info = SData.term_unbin(infobin)
Process.send_after(self(), {:calc_missing, 1}, 100)
- GenServer.cast(store, {:set_roots, [info.merkle_root]})
+ SApp.PageStore.set_roots(store, [info.merkle_root])
{infobin, info}
end
@@ -100,14 +100,14 @@ defmodule SApp.File do
end
def handle_call(:delete_shard, _from, state) do
- GenServer.call(state.store, :delete_store)
+ SApp.PageStore.delete_store(state.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}) ->
+ state.info != nil and SApp.PageStore.have_rec?(state.store, state.info.merkle_root) ->
mt = get_mt(state)
nblk = MT.block_count(mt)
[infohash: state.infohash,
@@ -185,7 +185,7 @@ defmodule SApp.File do
if state.infobin == nil and SData.bin_hash(infobin) == state.infohash do
Shard.Manager.save_state(state.id, infobin)
state = %{state | infobin: infobin, info: SData.term_unbin(infobin)}
- GenServer.cast(state.store, {:set_roots, [state.info.merkle_root]})
+ SApp.PageStore.set_roots(state.store, [state.info.merkle_root])
Process.send_after(self(), {:calc_missing, 1}, 100)
state
else
@@ -240,7 +240,7 @@ defmodule SApp.File do
def handle_info({:calc_missing, iter}, state) do
if state.info != nil do
Logger.info(":calc_missing for #{state.id|>Base.encode16}")
- missing = case GenServer.call(state.store, {:have_rec, state.info.merkle_root}) do
+ missing = case SApp.PageStore.have_rec?(state.store, state.info.merkle_root) do
true ->
meta = get_mt(state)
n_blocks = MT.block_count(meta)
@@ -266,7 +266,7 @@ defmodule SApp.File do
missing
false ->
Logger.info("Incomplete Merkle tree meta data, requesting info from peers.")
- GenServer.cast(state.store, {:set_roots, [state.info.merkle_root]})
+ SApp.PageStore.set_roots(state.store, [state.info.merkle_root])
Process.send_after(self(), {:calc_missing, iter + 1}, iter * 1000)
nil
end
@@ -302,7 +302,6 @@ defmodule SApp.File do
pieces = can_req |> Enum.sort() |> Enum.take(@concurrent_reqs - n_curr_req)
Enum.reduce(pieces, state, fn id, state ->
who = a_random_peer(state.missing[id])
- Logger.info("#{state.id|>Base.encode16} | Req #{id} to #{inspect who}")
SNet.Manager.send(who, {state.id, nil, {:get, id}})
Process.send_after(self(), {:req_timeout, id}, @req_timeout_msec)
put_in(state.reqs[id], who)
diff --git a/shard/lib/app/pagestore.ex b/shard/lib/app/pagestore.ex
index 0cbb10a..79d39b7 100644
--- a/shard/lib/app/pagestore.ex
+++ b/shard/lib/app/pagestore.ex
@@ -329,4 +329,11 @@ defmodule SApp.PageStore do
def set_roots(pid, roots) do
GenServer.cast(pid, {:set_roots, roots})
end
+
+ @doc"""
+ Delete the page store. The process is stopped and the data file is deleted from disk.
+ """
+ def delete_store(pid) do
+ GenServer.call(pid, :delete_store)
+ end
end
diff --git a/shard/lib/cli/cli.ex b/shard/lib/cli/cli.ex
index 8495b93..a9eaa95 100644
--- a/shard/lib/cli/cli.ex
+++ b/shard/lib/cli/cli.ex
@@ -105,7 +105,7 @@ defmodule SCLI do
end
defp handle_command(state, ["list"]) do
- IO.puts "Private conversations:"
+ IO.puts "\nPrivate conversations:\n----"
for {_chid, %SApp.Chat.PrivChat.Manifest{pk_list: pk_list}, _} <- Shard.Manager.list_shards do
pk_list
|> Enum.filter(&(&1 != state.pk))
@@ -114,10 +114,11 @@ defmodule SCLI do
|> IO.puts
end
- IO.puts "Public channels we are connected to:"
+ IO.puts "\nPublic channels we are connected to:\n----"
for {_chid, %SApp.Chat.Manifest{channel: chan}, _} <- Shard.Manager.list_shards do
IO.puts "##{chan}"
end
+ IO.puts ""
state
end
@@ -209,10 +210,41 @@ defmodule SCLI do
end
defp handle_command(state, ["shards"]) do
+ IO.puts("\nList of shards:\n----")
Shard.Manager.list_shards
|> Enum.map(&(ShardURI.from_manifest(elem(&1, 1))))
|> Enum.sort()
|> Enum.map(&IO.puts/1)
+ IO.puts("")
+ state
+ end
+
+ defp handle_command(state, ["delete", uri]) do
+ manifest = ShardURI.to_manifest uri
+ id = SData.term_hash manifest
+ case Shard.Manager.delete(id) do
+ :ok -> IO.puts "OK"
+ {:error, :not_found} -> IO.puts "Shard not found"
+ {:error, :pinned} -> IO.puts "Shard is pinned, could not be deleted"
+ end
+ state
+ end
+
+ defp handle_command(state, ["info", uri]) do
+ manifest = ShardURI.to_manifest uri
+ case manifest do
+ %SApp.File.Manifest{} ->
+ pid = Shard.Manager.find_or_start manifest
+ info = GenServer.call(pid, :get_info)
+ IO.puts(inspect(info, pretty: true, width: 40))
+ _ ->
+ IO.puts("Info not supported for this shard")
+ end
+ state
+ end
+
+ defp handle_command(state, ["help"]) do
+ IO.puts("See README.md for help")
state
end
diff --git a/shard/lib/manager.ex b/shard/lib/manager.ex
index ed21380..efa9189 100644
--- a/shard/lib/manager.ex
+++ b/shard/lib/manager.ex
@@ -412,4 +412,11 @@ defmodule Shard.Manager do
def list_shards() do
for [{id, m, why, _}] <- :dets.match(@shard_db, :"$1"), do: {id, m, why}
end
+
+ @doc"""
+ Check if we are storing this shard
+ """
+ def have_shard?(shard_id) do
+ :dets.lookup(@shard_db, shard_id) != []
+ end
end