Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkaspa committed Jun 25, 2016
1 parent ef653c5 commit 68ea17b
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 113 deletions.
6 changes: 6 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Validate before build
- Add Supervisors functionality
- Named nodes with graph prefix
- Improve test
- Improve API
- Update to GenStage
5 changes: 3 additions & 2 deletions lib/exstreme/gnode/behaviour.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ defmodule Exstreme.GNode.Behaviour do
#TODO use counters
end

def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, opts)
def start_link(params \\ []) do
nid = Keyword.get(params, :nid)
GenServer.start_link(__MODULE__, params, name: nid)
end

def init(params) do
Expand Down
8 changes: 5 additions & 3 deletions lib/exstreme/graph.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ defmodule Exstreme.Graph do
"""
alias __MODULE__

@type t :: %Graph{params: [key: term], nodes: %{key: [key: term]}, connections: %{key: atom}}
defstruct params: [], nodes: %{}, connections: %{}
@typedoc """
"""
@type t :: %Graph{name: String.t,params: [key: term], nodes: %{key: [key: term]}, connections: %{key: atom}}
defstruct name: '', params: [], nodes: %{}, connections: %{}

@doc """
"""
Expand Down Expand Up @@ -119,7 +121,7 @@ defmodule Exstreme.Graph do
end

@spec get_nodes_func(atom, {atom, atom}, [atom], ((atom, {atom, atom}) -> boolean)) :: [atom]
defp get_nodes_func(node, pair = {from, to}, res, func) do
defp get_nodes_func(node, {from, to} = pair, res, func) do
case to do
to when is_atom(to) ->
{ok, add_node} = func.(node, pair)
Expand Down
14 changes: 9 additions & 5 deletions lib/exstreme/graph_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ defmodule Exstreme.GraphBuilder do
alias Exstreme.GNode.Funnel
alias Exstreme.GNode.Common
alias Exstreme.Graph
alias Exstreme.GraphValidator

@doc """
Builds the Supervision tree for the graph
"""
@spec build(Graph.t) :: Graph.t
@spec build(Graph.t) :: Graph.t | GraphValidator.error
def build(graph) do
graph
|> update_nodes_relations
|> start_nodes
|> connect_nodes
with :ok <- GraphValidator.validate(graph) do
graph
|> update_nodes_relations
|> start_nodes
|> connect_nodes
end
end

#private
Expand Down
57 changes: 37 additions & 20 deletions lib/exstreme/graph_creator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,34 @@ defmodule Exstreme.GraphCreator do
"""
alias Exstreme.Graph

@default_length_name 20

@typedoc """

"""
@type update_map_func :: (%{key: atom} -> %{key: atom})

@doc """
"""
@spec create_graph([key: term]) :: Graph.t
def create_graph(params \\ []), do: %Graph{params: params}
def create_graph(params) do
name =
:crypto.strong_rand_bytes(@default_length_name)
|> Base.url_encode64
|> binary_part(0, @default_length_name)
create_graph(name, params)
end

@doc """
"""
@spec create_graph(String.t, [key: term]) :: Graph.t
def create_graph(name, params), do: %Graph{name: name, params: params}

@doc """
"""
@spec create_node(Graph.t, [key: term]) :: {Graph.t, atom}
def create_node(graph = %Graph{nodes: nodes}, params \\ []) do
key = next_node_key(nodes)
def create_node(graph = %Graph{name: name, nodes: nodes}, params \\ []) do
key = next_node_key(name, nodes)

new_graph = update_in(graph.nodes, &(Map.put(&1, key, params)))
{new_graph, key}
Expand All @@ -23,8 +39,8 @@ defmodule Exstreme.GraphCreator do
@doc """
"""
@spec create_broadcast(Graph.t, [key: term]) :: {Graph.t, atom}
def create_broadcast(graph = %Graph{nodes: nodes}, params \\ []) do
key = next_broadcast_key(nodes)
def create_broadcast(graph = %Graph{name: name, nodes: nodes}, params \\ []) do
key = next_broadcast_key(name, nodes)

new_graph = update_in(graph.nodes, &(Map.put(&1, key, params)))
{new_graph, key}
Expand All @@ -33,8 +49,8 @@ defmodule Exstreme.GraphCreator do
@doc """
"""
@spec create_funnel(Graph.t, [key: term]) :: {Graph.t, atom}
def create_funnel(graph = %Graph{nodes: nodes}, params \\ []) do
key = next_funnel_key(nodes)
def create_funnel(graph = %Graph{name: name, nodes: nodes}, params \\ []) do
key = next_funnel_key(name, nodes)

new_graph = update_in(graph.nodes, &(Map.put(&1, key, params)))
{new_graph, key}
Expand Down Expand Up @@ -153,29 +169,30 @@ defmodule Exstreme.GraphCreator do
end
end

@spec next_node_key(%{key: atom}) :: atom
defp next_node_key(nodes) do
next_key(nodes, "n")
@spec next_node_key(String.t, %{key: atom}) :: atom
defp next_node_key(name, nodes) do
next_key(name, nodes, "n")
end

@spec next_broadcast_key(%{key: atom}) :: atom
defp next_broadcast_key(nodes) do
next_key(nodes, "b")
@spec next_broadcast_key(String.t, %{key: atom}) :: atom
defp next_broadcast_key(name, nodes) do
next_key(name, nodes, "b")
end

@spec next_funnel_key(%{key: atom}) :: atom
defp next_funnel_key(nodes) do
next_key(nodes, "f")
@spec next_funnel_key(String.t, %{key: atom}) :: atom
defp next_funnel_key(name, nodes) do
next_key(name, nodes, "f")
end

@spec next_key(%{key: atom}, String.t) :: atom
defp next_key(map, letter) do
@spec next_key(String.t, %{key: atom}, String.t) :: atom
defp next_key(name, map, letter) do
prefix = "#{letter}_#{name}_"
count =
map
|> Map.keys
|> Enum.map(&Atom.to_string/1)
|> Enum.filter(fn(str) -> String.starts_with?(str, letter) end)
|> Enum.filter(&(String.starts_with?(&1, prefix)))
|> Enum.count
String.to_atom("#{letter}#{count + 1}")
String.to_atom("#{prefix}#{count + 1}")
end
end
24 changes: 14 additions & 10 deletions lib/exstreme/graph_validator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ defmodule Exstreme.GraphValidator do
@moduledoc """
"""

@typedoc """
"""
@type error :: {:error, String.t}

@doc """
"""
@spec validate(Graph.t) :: :ok | {:error, []}
@spec validate(Graph.t) :: :ok | error
def validate(graph) do
with :ok <- validate_must_have_connections(graph),
:ok <- validate_start_nodes(graph),
Expand All @@ -15,18 +19,18 @@ defmodule Exstreme.GraphValidator do

# private

@spec validate_must_have_connections(Graph.t) :: :ok | {:error, []}
@spec validate_must_have_connections(Graph.t) :: :ok | error
defp validate_must_have_connections(graph) do
nodes_amount = Graph.count_nodes(graph)
connections_amount = Graph.count_connections(graph)
if nodes_amount > 0 and connections_amount == 0 do
{:error, []}
{:error, ""}
else
:ok
end
end

@spec validate_start_nodes(Graph.t) :: :ok | {:error, []}
@spec validate_start_nodes(Graph.t) :: :ok | error
defp validate_start_nodes(graph) do
start_nodes = Graph.find_start_node(graph)

Expand All @@ -35,28 +39,28 @@ defmodule Exstreme.GraphValidator do
do: :ok
end

@spec validate_should_start_with_one_node([atom, ...]) :: :ok | {:error, []}
@spec validate_should_start_with_one_node([atom, ...]) :: :ok | error
defp validate_should_start_with_one_node([_]), do: :ok

defp validate_should_start_with_one_node(_), do: {:error, []}
defp validate_should_start_with_one_node(_), do: {:error, ""}

@spec validate_should_start_with_node([atom, ...]) :: :ok | {:error, []}
@spec validate_should_start_with_node([atom, ...]) :: :ok | error
defp validate_should_start_with_node([start_node]) do
start_char = start_node |> Atom.to_string |> String.first
if start_char == "n" do
:ok
else
{:error, []}
{:error, ""}
end
end

@spec validate_connectivity(Graph.t) :: :ok | {:error, []}
@spec validate_connectivity(Graph.t) :: :ok | error
defp validate_connectivity(graph) do
stats = Graph.connections_stats(graph)
if stats[:unconnected] == nil do
:ok
else
{:error, []}
{:error, ""}
end
end
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Exstreme.Mixfile do
def project do
[app: :exstreme,
version: "0.0.1",
elixir: "~> 1.2",
elixir: "~> 1.3",
elixirc_paths: elixirc_paths(Mix.env),
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
@@ -1 +1 @@
%{"dialyxir": {:hex, :dialyxir, "0.3.3"}}
%{"dialyxir": {:hex, :dialyxir, "0.3.3", "2f8bb8ab4e17acf4086cae847bd385c0f89296d3e3448dc304c26bfbe4b46cb4", [:mix], []}}
2 changes: 1 addition & 1 deletion test/exstreme/graph_builder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Exstreme.GraphBuilderTest do
alias Exstreme.Graph
doctest Exstreme.GraphBuilder

test "creates a graph" do
test "creates a graph and check built params" do
graph_built = GraphBuilder.build(create_graph)
assert graph_built != create_graph
Enum.each(graph_built.nodes, fn({_, params}) ->
Expand Down
Loading

0 comments on commit 68ea17b

Please sign in to comment.