Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[Lua] Removed lua simulation support
[simgrid.git] / examples / lua / chord / chord.lua
diff --git a/examples/lua/chord/chord.lua b/examples/lua/chord/chord.lua
deleted file mode 100644 (file)
index bb763bd..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
--- A SimGrid Lua implementation of the Chord DHT
-
-require("simgrid")
-
-nb_bits = 24
-nb_keys = 2^nb_bits
-comp_size = 0
-comm_size = 10
-timeout = 50
-max_simulation_time = 1000
-stabilize_delay = 20
-fix_fingers_delay = 120
-check_predecessor_delay = 120
-lookup_delay = 10
-
--- current node (don't worry, globals are duplicated in each process)
-my_node = {
-  id = my_id,
-  next_finger_to_fix = 1,
-  fingers = {},
-  predecessor = nil,
-  comm_recv = nil
-}
-
--- Main function of each Chord process
--- Arguments:
--- - my id
--- - the id of a guy I know in the system (except for the first node)
-function node(...)
-
-  -- TODO simplify the parameters
-  local known_id
-  local args = {...}
-  my_node.id = tonumber(args[1])
-  if #args == 4 then
-    known_id = tonumber(args[2])
-  end
-
-  -- initialize the node
-  for i = 1, nb_bits do
-    my_node.fingers[i] = my_node.id
-  end
-  my_node.comm_recv = simgrid.task.irecv(my_node.id)
-
-  -- join the ring
-  local join_success = false
-  if known_id == nil then
-    -- first node
-    create()
-    join_success = true
-  else
-    join_success = join(known_id)
-  end
-
-  -- main loop
-  if join_success then
-
-    local now = simgrid.get_clock()
-    local next_stabilize_date = now + stabilize_delay
-    local next_fix_fingers_date = now + fix_fingers_delay
-    local next_check_predecessor_date = now + check_predecessor_delay
-    local next_lookup_date = now + lookup_delay
-
-    local task, success
-
-    while now < max_simulation_time do
-
-      task, success = simgrid.comm.test(my_node.comm_recv)
-
-      if task then
-       -- I received a task: answer it
-        my_node.comm_recv = simgrid.task.irecv(my_node.id)
-       handle_task(task)
-      elseif failed then
-        -- the communication has failed: nevermind
-        my_node.comm_recv = simgrid.task.irecv(my_node.id)
-      else
-        -- no task was received: do periodic calls
-       if now >= next_stabilize_date then
-          stabilize()
-         next_stabilize_date = simgrid.get_clock() + stabilize_delay
-
-       elseif now >= next_fix_fingers_date then
-         fix_fingers()
-         next_fix_fingers_date = simgrid.get_clock() + fix_fingers_delay
-
-       elseif now >= next_check_predecessor_date then
-         check_predecessor()
-         next_check_predecessor_date = simgrid.get_clock() + check_predecessor_delay
-       elseif now >= next_lookup_date then
-         random_lookup()
-         next_lookup_date = simgrid.get_clock() + lookup_delay
-
-       else
-         -- nothing to do: sleep for a while
-         simgrid.process.sleep(5)
-       end
-      end
-      now = simgrid.get_clock()
-    end -- while
-
-    -- leave the ring
-    leave()
-  end
-end
-
--- Makes the current node leave the ring
-function leave()
-
-  simgrid.info("Leaving the ring")
-  -- TODO: notify others
-end
-
--- This function is called when the current node receives a task.
--- - task: the task received
-function handle_task(task)
-
-  local type = task.type
-
-  if type == "find successor" then
-
-    simgrid.info("Received a 'find successor' request from " .. task.answer_to ..
-        " for id " .. task.request_id)
-
-    -- is my successor the successor?
-    if is_in_interval(task.request_id, my_node.id + 1, my_node.fingers[1]) then
-
-      simgrid.info("Sending back a 'find successor answer' to " ..
-          task.answer_to .. ": the successor of " .. task.request_id ..
-         " is " .. my_node.fingers[1])
-
-      local ans_task = simgrid.task.new("", comp_size, comm_size)
-      ans_task.type = "find successor answer"
-      ans_task.request_id = task.request_id
-      ans_task.answer = my_node.fingers[1]
-      ans_task:dsend(task.answer_to)
-    else
-      -- forward the request to the closest preceding finger in my table
-
-      simgrid.info("Forwarding the 'find successor' request to my closest preceding finger")
-
-      local next_task = simgrid.task.new("", comp_size, comm_size)
-      next_task.type = "find successor"
-      next_task.request_id = task.request_id
-      next_task.answer_to = task.answer_to
-      next_task:dsend(closest_preceding_node(next_task.request_id))
-    end
-
-  elseif type == "get predecessor" then
-    local ans_task = simgrid.task.new("", comp_size, comm_size)
-    ans_task.type = "get predecessor answer"
-    ans_task.answer = my_node.predecessor
-    ans_task:dsend(task.answer_to)
-
-  elseif type == "notify" then
-    -- someone is telling me that he may be my new predecessor
-    notify(task.request_id)
-
-  elseif type == "predecessor leaving" then
-    -- TODO
-
-  elseif type == "successor_leaving" then
-    -- TODO
-
-  elseif type == "find successor answer" then
-    -- ignoring
-
-  elseif type == "get predecessor answer" then
-    -- ignoring
-
-  else
-    error("Unknown type of task received: " .. task.type)
-  end
-end
-
--- Returns whether an id belongs to the interval [a, b[.
--- The parameters are normalized to make sure they are between 0 and nb_keys - 1.
--- 1 belongs to [62, 3].
--- 1 does not belong to [3, 62].
--- 63 belongs to [62, 3].
--- 63 does not belong to [3, 62].
--- 24 belongs to [21, 29].
--- 24 does not belong to [29, 21].
-function is_in_interval(id, a, b)
-
-  -- normalize the parameters
-  id = id % nb_bits
-  a = a % nb_bits
-  b = b % nb_bits
-  -- make sure a <= b and a <= id
-  if b < a then
-    b = b + nb_keys
-  end
-
-  if id < a then
-    id = id + nb_keys
-  end
-
-  return id <= b
-end
-
--- Returns whether the current node is in the ring.
-function has_joined()
-
-  return my_node.fingers[1] ~= nil
-end
-
--- Creates a new Chord ring.
-function create()
-  my_node.predecessor = nil
-  my_node.fingers[1] = my_node.id
-end
-
--- Attemps to join the Chord ring.
--- - known_id: id of a node already in the ring
--- - return value: true if the join was successful
-function join(known_id)
-
-  simgrid.info("Joining the ring with id " .. my_node.id .. ", knowing node " .. known_id)
-
-  local successor = remote_find_successor(known_id, my_node.id)
-  if successor == nil then
-    simgrid.info("Cannot join the ring.")
-    return false
-  end
-
-  my_node.predecessor = nil
-  my_node.fingers[1] = successor
-  return true
-end
-
--- Returns the closest preceding finger of an id with respect to the finger
--- table of the current node.
--- - id: the id to find
--- - return value: the closest preceding finger of that id
-function closest_preceding_node(id)
-
-  for i = nb_bits, 1, -1 do
-    if is_in_interval(my_node.fingers[i], my_node.id + 1, id - 1) then
-      -- finger i is the first one before id
-      return my_node.fingers[i]
-    end
-  end
-end
-
--- Finds the successor of an id
--- id: the id to find
--- return value: the id of the successor, or nil if the request failed
-function find_successor(id)
-
-  if is_in_interval(id, my_node.id + 1, my_node.fingers[1]) then
-    -- my successor is the successor
-    return my_node.fingers[1]
-  end
-
-  -- ask to the closest preceding finger in my table
-  local ask_to = closest_preceding_node(id)
-  return remote_find_successor(ask_to, id)
-end
-
--- Asks a remote node the successor of an id.
--- ask_to: id of a remote node to ask to
--- id: the id to find
--- return value: the id of the successor, or nil if the request failed
-function remote_find_successor(ask_to, id)
-
-  local task = simgrid.task.new("", comp_size, comm_size)
-  task.type = "find successor"
-  task.request_id = id
-  task.answer_to = my_node.id
-
-  simgrid.info("Sending a 'find successor' request to " .. ask_to .. " for id " .. id)
-  if task:send(ask_to, timeout) then
-    -- request successfully sent: wait for an answer
-
-    simgrid.info("Sent the 'find successor' request to " .. ask_to ..
-        " for id " .. id .. ", waiting for the answer")
-
-    while true do
-      task = simgrid.comm.wait(my_node.comm_recv, timeout)
-      my_node.comm_recv = simgrid.task.irecv(my_node.id)
-    
-      if not task then
-       -- failed to receive the answer
-       simgrid.info("Failed to receive the answer to my 'find successor' request")
-       return nil
-      else
-       -- a task was received: is it the expected answer?
-       if task.type ~= "find successor answer" or task.request_id ~= id then
-          -- this is not our answer
-         simgrid.info("Received another request of type " .. task.type)
-         handle_task(task)
-       else
-         -- this is our answer
-         simgrid.info("Received the answer to my 'find successor' request for id " ..
-             id .. ": the successor is " .. task.answer)
-         return task.answer
-       end
-      end
-    end
-  else
-    simgrid.info("Failed to send the 'find successor' request to " .. ask_to ..
-        " for id " .. id)
-  end
-
-  return successor
-end
-
--- Asks a remote node its predecessor.
--- ask_to: id of a remote node to ask to
--- return value: the id of its predecessor, or nil if the request failed
-function remote_get_predecessor(ask_to)
-
-  local task = simgrid.task.new("", comp_size, comm_size)
-  task.type = "get predecessor"
-  task.answer_to = my_node.id
-
-  if task:send(ask_to, timeout) then
-    -- request successfully sent: wait for an answer
-    while true do
-      task = simgrid.comm.wait(my_node.comm_recv, timeout)
-      my_node.comm_recv = simgrid.task.irecv(my_node.id)
-    
-      if not task then
-       -- failed to receive the answer
-       return nil
-      else
-       -- a task was received: is it the expected answer?
-       if task.type ~= "get predecessor answer" then
-          -- this is not our answer
-         handle_task(task)
-       else
-         -- this is our answer
-         -- FIXME make sure the message answers to this particular request
-         return task.answer
-       end
-      end
-    end
-  end
-
-  return successor
-end
-
--- Checks the immediate successor of the current node.
-function stabilize()
-
-  local candidate
-  local successor = my_node.fingers[1]
-  if successor ~= my_node.id then
-    candidate = remote_get_predecessor(successor)
-  else
-    candidate = my_node.predecessor
-  end
-
-  -- this node is a candidate to become my new successor
-  if candidate ~= nil and is_in_interval(candidate, my_node.id + 1, successor - 1) then
-    my_node.fingers[1] = candidate
-  end
-
-  if successor ~= my_node.id then
-    remote_notify(successor, my_node.id)
-  end
-end
-
--- Notifies the current node that its predecessor my have changed
--- - candidate_predecessor: the possible new predecessor
-function notify(candidate_predecessor)
-
-  if my_node.predecessor == nil or is_in_interval(candidate_predecessor,
-      my_node.predecessor + 1, my_node.id - 1) then
-    my_node.predecessor = candidate_predecessor
-  end
-end
-
--- Notifies a remote node that its predecessor my have changed.
--- - notify_to
--- - candidate the possible new predecessor
-function remote_notify(notify_to, candidate_predecessor)
-
-  local task = simgrid.task.new("", comp_size, comm_size)
-  task.type = "notify"
-  task.request_id = candidate_predecessor
-  task:dsend(notify_to)
-end
-
--- Refreshes the finger table of the current node.
-function fix_fingers()
-
-  local i = my_node.next_finger_to_fix
-  local id = find_successor(my_node.id + 2^i)
-  if id ~= nil then
-    if id ~= my_node.fingers[i] then
-      my_node.fingers[i] = id
-    end
-    my_node.next_finger_to_fix = (i % nb_bits) + 1
-  end
-end
-
--- Checks whether the predecessor of the current node has failed.
-function check_predecessor()
-  -- TODO
-end
-
--- Performs a find successor request to an arbitrary id.
-function random_lookup()
-
-  find_successor(1337)
-end
-
-simgrid.platform(arg[1] or "../../msg/msg_platform.xml")
-simgrid.application(arg[2] or "../../msg/chord/chord90.xml")
-simgrid.run()
-