bitwalker / libring Goto Github PK
View Code? Open in Web Editor NEWA fast consistent hash ring implementation in Elixir
License: MIT License
A fast consistent hash ring implementation in Elixir
License: MIT License
I'm trying to run the tests but it throws me the following error:
(CompileError) test/hashring_test.exs:3: module :eqc_gen is not loaded and could not be found
I'm using Elixir 1.7.3 and Erlang 21.0.5
This can be verified pretty easily in the shell, but there's an erlang mailing list thread that gives examples but here's salient bit
2> erlang:phash2(aaa).
26481
3> erlang:phash2(bbb).
26754
4> erlang:phash2(ccc).
27027
The takeaway seems to be it works great for any term except atoms. One possibility is to call :erlang.term_to_binary
on the atom, or alternatively wrap it in a tuple or list.
When running an app which uses libring in Elixir 1.10 I get the following deprecation message:
warning: :simple_one_for_one strategy is deprecated, please use DynamicSupervisor instead
(elixir 1.10.0) lib/supervisor.ex:604: Supervisor.init/2
(elixir 1.10.0) lib/supervisor.ex:556: Supervisor.start_link/2
(libring 1.4.0) lib/app.ex:13: HashRing.App.start/2
(kernel 6.5.1) application_master.erl:277: :application_master.start_it_old/4
:logger
needs to be listed in dependencies otherwise you might get this error if :libring
happens to be started first:
=INFO REPORT==== 15-Oct-2018::21:41:03 ===
application: libring
exited: {bad_return,
{{'Elixir.HashRing.App',start,[normal,[]]},
{'EXIT',
{#{'__exception__' => true,
'__struct__' => 'Elixir.RuntimeError',
message =>
<<"cannot use Logger, the :logger application is not running">>},
[{'Elixir.Logger.Config','__data__',0,
[{file,"lib/logger/config.ex"},{line,53}]},
See PR #16
{:ok, pid} = HashRing.Managed.new(:myring)
** (exit) exited in: GenServer.call(HashRing.Supervisor, {:start_child, [[name: :myring]]}, :infinity)
** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
(elixir) lib/gen_server.ex:729: GenServer.call/3
I tried creating a hash ring with nodes 1 -> 1024, and noticed that it would error out at 805 every time.
For example, you can test with this:
0..804 |> Enum.reduce(HashRing.new, fn (n, r) -> IO.inspect(n); r |> HashRing.add_node(n) end) # => works
0..805 |> Enum.reduce(HashRing.new, fn (n, r) -> IO.inspect(n); r |> HashRing.add_node(n) end) # => breaks
Error output
** (ErlangError) erlang error: {:key_exists, 2854800734}
(stdlib) gb_trees.erl:318: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:297: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:297: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:280: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:297: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:280: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:297: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:280: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:297: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:280: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:297: :gb_trees.insert_1/4
(stdlib) gb_trees.erl:277: :gb_trees.insert/3
(libring) lib/ring.ex:104: anonymous fn/3 in HashRing.add_node/3
(elixir) lib/enum.ex:1785: Enum.reduce_range_inc/4
My expectation was that the name option would work the same way as a GenServer. The libring
prefix made finding the process non-trivial:
def start_link(options) do
name = Keyword.fetch!(options, :name)
GenServer.start_link(__MODULE__, options, name: :"libring_#{name}")
end
See PR #27 for implementation.
https://github.com/discordapp/ex_hash_ring has the exact same module name.
I was testing a lookup with 3 nodes in the ring. For the same key, running the lookup in nodes b and c returned a. Running the lookup in node a, returned b.
Turns out the managed ring is not initialized with the local node. Line 32 in HashRing.Worker.init/1 should be changed to:
nodes = Node.list([:this, :connected])
Right now the README says to use libring 1.1. I believe that should be 1.0.1 since 1.1 doesn't exist in hex
This (https://github.com/bitwalker/libring/blob/master/lib/worker.ex#L77) should be:
{:noreply, {HashRing.add_node(ring, node), b, w}}
new state is ring
instead of {ring, b, w}
I don't know if this is an issue of this lib or is elsewhere, but when adding pids to a HashRing I get this problem:
Suppose pid1 = #PID<0.433.0>
and pid2 = #PID<21396.433.0>
Processes in different nodes.
> r = HashRing.new()
#<Ring[]>
> r = HashRing.add_node(r, pid1)
#<Ring[#PID<0.433.0>]>
> r = HashRing.add_node(r, pid2)
#<Ring[#PID<0.433.0>]>
It's like they were the same for HashRing
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.