Skip to content

Instantly share code, notes, and snippets.

@fairchild
Created February 27, 2009 21:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fairchild/71700 to your computer and use it in GitHub Desktop.
Save fairchild/71700 to your computer and use it in GitHub Desktop.
proposed API for ditributed has table
# sample skeleton for a ruby API based on the ideas from http://www.oceanstore.org/publications/papers/pdf/iptps03-api.pdf
class DistributeKeyBasedRouter
def initialize(deliver_to_class, deliver_class_method = :delivered)
@delivery_callback_class = deliver_to_class
@delivery_callback_method = deliver_class_method
end
# Route the given message to the node conatining key
# The optional hint argument specifies a node that should
# be used as a first hop in routing the message
def route(key, msg=nil, node_handle=nil)
# FFI send message to chimera to be routed
end
def forward(key, msg=nil, node_handle=nil)
end
# Callback invoked on the node that is the root for the key, when node contains the key.
# Note, this is the call back that should hook into your application
def deliver(key, msg=nil)
@delivery_callback_class.send( @delivery_callback_method, key, msg )
end
private
# Returns a list of num number of nodes that can be used as next hops towards the key
def local_lookup(key, num=1, safe=false)
[]
end
# returns an onordered set of neighbors of the local node in ID space, upto num nodes.
def neighbor_set
[]
end
# Returns an ordered set of nodehandles on which replicas of the object with give key can gbe stored.
# The call returns nodes with a rank up to and including max_rank.
# If max_rank exceeds the available replica size, then the maximum that is available is returned.
def replica_set(key, max_rank=1)
[]
end
# Callback invoked when a node has either joned or left the nodes neigbor_set
def update(node_handle, joined)
end
# Provides information about ranges of keys for which the node is currently a root of given rank.
def range(node_handle, rank, l_key, r_key)
true || false
end
end
# just working at an API for a distributed hash table making use of the DistributeKeyBasedRouter
class DHT
BASE_DIR='./'
# alias_method <<(value)
# alias_method [key]=(value)
def self.put(value, key=sha1(value) )
msg = {:action=>'store', :value=>value}.to_yaml
DistributeKeyBasedRouter.new.route(key, msg )
key
end
def self.get(key)
msg = {:action=>'retreive', :value=>value}.to_yaml
DistributeKeyBasedRouter.new.route(key, msg )
end
def self.store(key, value)
File.open(File.join(BASE_DIR, key.to_s), 'w') {|f| f.write(value) }
end
def self.retreive(key)
File.read(File.join(BASE_DIR, key.to_s))
end
# This is the callback that the distributed router should invoke upon a message delivery
def self.delivered(key, msg)
printf "received: %s => %s", key, msg
deserialized_message = ::YAML::load(msg)
puts deserialized_message.inspect
DHT.send(deserialized_message[:action].to_sym, key.to_s, deserialized_message[:value])
end
end
# ==========
# = sample =
# ==========
kbr = DistributeKeyBasedRouter.new(DHT)
value = 'Put me in the dht.'
key = DHT.put(value)
# kbr.route(key, {:action=>'store', :value=>'Hello'}.to_yaml)
# ... eventually, within log(N)
# kbr.deliver(123, msg) -> invokes DHT.store(value) on the receiving node
val = DHT.get(key)
puts "success: #{val} retreived" if val == value
DHT.put("new value", key) #updates the entry
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment