Packages
(BETA) Distributed shared dictionary using master/slave replication and slave to master failover
Current section
Files
Jump to
Current section
Files
lib/distributed_attribute_server.ex
defmodule DistributedAttributeServer do
defmacro __using__(_opts) do
quote do
use DistributedAttributeServer.Master
use DistributedAttributeServer.Slave
use DistributedAttributeServer.LocalAttributeServer
alias DistributedAttributeServer.States.MasterState, as: MasterState
alias DistributedAttributeServer.States.SlaveState, as: SlaveState
def start_link _, _ do
start_link
end
def start_link do
unless master_assigned? do
master_lock_key = ((__MODULE__ |> to_string) <> ".MasterLock")
if run_for_master master_lock_key do
init_master
#:global.del_lock {master_lock_key, self}
else
init_slave
end
else
init_slave
end
end
defp ensure_started do
start_link
end
defp registered_locally? do
Process.whereis __MODULE__
end
def get(attr) do
ensure_started
if master? do
get_local attr
else
log "SLAVE: asking master for `get` #{:i.i attr}"
send master_receive_pid, {self, :get, attr}
receive do
{:get_response, value} -> value
_ -> IO.puts :stderr, "Unexpected message received"
end
end
end
def set(attr, value) do
ensure_started
if master? do
set_local attr, value
log "MASTER: broadcasting to slaves `set` #{:i.i attr}=#{:i.i value}"
master_broadcast {:set, attr, value}
else
log "SLAVE: sending master `set` #{:i.i attr}=#{:i.i value}"
send master_receive_pid, {self, :set, attr, value}
end
end
def set_all(attributes) do
ensure_started
if master? do
set_all_local attributes
log "MASTER: broadcasting to slaves `set_all` #{:i.i attributes}"
master_broadcast {:set_all, attributes}
else
log "SLAVE: sending master `set_all` #{:i.i attributes}"
send master_receive_pid, {self, :set_all, attributes}
end
end
def all do
ensure_started
if master? do
all_local
else
log "SLAVE: asking master for `all`"
send master_receive_pid, {self, :all}
receive do
{:all_response, value} -> value
_ -> IO.puts :stderr, "Unexpected message received"
end
end
end
def clear do
ensure_started
if master? do
clear_local
log "MASTER: broadcasting to slaves `clear`"
master_broadcast {:clear}
else
send master_receive_pid, {self, :clear}
end
end
def size do
ensure_started
if master? do
size_local
else
send master_receive_pid, {self, :size}
receive do
{:size_response, value} -> value
_ -> IO.puts :stderr, "Unexpected message received"
end
end
end
defp log str do
IO.puts str
end
end
end
end