A
lgorithmique
N
umérique
D
istribuée
Public GIT Repository
projects
/
simgrid.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
model-checker : update tesh
[simgrid.git]
/
examples
/
lua
/
chord
/
chord.lua
diff --git
a/examples/lua/chord/chord.lua
b/examples/lua/chord/chord.lua
index
0e97f43
..
523b150
100644
(file)
--- a/
examples/lua/chord/chord.lua
+++ b/
examples/lua/chord/chord.lua
@@
-13,7
+13,7
@@
fix_fingers_delay = 120
check_predecessor_delay = 120
lookup_delay = 10
check_predecessor_delay = 120
lookup_delay = 10
--- current node (don't worry, globals are duplicated in each process)
+-- current node (don't worry, globals are duplicated in each
simulated
process)
my_node = {
id = my_id,
next_finger_to_fix = 1,
my_node = {
id = my_id,
next_finger_to_fix = 1,
@@
-26,18
+26,30
@@
my_node = {
-- Arguments:
-- - my id
-- - the id of a guy I know in the system (except for the first node)
-- Arguments:
-- - my id
-- - the id of a guy I know in the system (except for the first node)
-function node(my_id, known_id)
+function node(...)
+
+ -- TODO simplify the deployment file
+ local known_id
+ local args = {...}
+ my_node.id = tonumber(args[1])
+ if #args == 4 then
+ known_id = tonumber(args[2])
+ end
- simgrid.debug("Hello, I'm a node with id " .. my_id .. " and I know " .. known_id)
+ -- 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
-- join the ring
- local success = false
+ local
join_
success = false
if known_id == nil then
-- first node
create()
if known_id == nil then
-- first node
create()
- success = true
+
join_
success = true
else
else
- success = join(known_id)
+
join_
success = join(known_id)
end
-- main loop
end
-- main loop
@@
-49,17
+61,19
@@
function node(my_id, known_id)
local next_check_predecessor_date = now + check_predecessor_delay
local next_lookup_date = now + lookup_delay
local next_check_predecessor_date = now + check_predecessor_delay
local next_lookup_date = now + lookup_delay
- local task
- my_node.comm_recv = simgrid.task.irecv(my_node.id)
+ local task, err
while now < max_simulation_time do
while now < max_simulation_time do
- task
= simgrid.comm.test(node.comm_recv
)
+ task
, err = my_node.comm_recv:test(
)
if task then
-- I received a task: answer it
my_node.comm_recv = simgrid.task.irecv(my_node.id)
handle_task(task)
if task then
-- I received a task: answer it
my_node.comm_recv = simgrid.task.irecv(my_node.id)
handle_task(task)
+ elseif err 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
else
-- no task was received: do periodic calls
if now >= next_stabilize_date then
@@
-73,6
+87,7
@@
function node(my_id, known_id)
elseif now >= next_check_predecessor_date then
check_predecessor()
next_check_predecessor_date = simgrid.get_clock() + check_predecessor_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
elseif now >= next_lookup_date then
random_lookup()
next_lookup_date = simgrid.get_clock() + lookup_delay
@@
-90,6
+105,13
@@
function node(my_id, known_id)
end
end
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)
-- This function is called when the current node receives a task.
-- - task: the task received
function handle_task(task)
@@
-98,17
+120,28
@@
function handle_task(task)
if type == "find successor" then
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
-- 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])
+
task.type = "find successor answer"
task.answer = my_node.fingers[1]
task:dsend(task.answer_to)
else
-- forward the request to the closest preceding finger in my table
task.type = "find successor answer"
task.answer = my_node.fingers[1]
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")
task:dsend(closest_preceding_node(task.request_id))
end
elseif type == "get predecessor" then
task:dsend(closest_preceding_node(task.request_id))
end
elseif type == "get predecessor" then
+ task.type = "get predecessor answer"
task.answer = my_node.predecessor
task:dsend(task.answer_to)
task.answer = my_node.predecessor
task:dsend(task.answer_to)
@@
-160,17
+193,33
@@
function is_in_interval(id, a, b)
return id <= b
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)
-- 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
local successor = remote_find_successor(known_id, my_node.id)
if successor == nil then
+ simgrid.info("Cannot join the ring.")
return false
end
return false
end
- my_node.finger[1] = successor
+ my_node.predecessor = nil
+ my_node.fingers[1] = successor
return true
end
return true
end
@@
-181,16
+230,16
@@
end
function closest_preceding_node(id)
for i = nb_bits, 1, -1 do
function closest_preceding_node(id)
for i = nb_bits, 1, -1 do
- if is_in_interval(my_node.fingers[i]
.id
, my_node.id + 1, id - 1) then
+ if is_in_interval(my_node.fingers[i], my_node.id + 1, id - 1) then
-- finger i is the first one before id
-- finger i is the first one before id
- return my_node.fingers[i]
.id
+ return my_node.fingers[i]
end
end
end
-- Finds the successor of an id
-- id: the id to find
end
end
end
-- Finds the successor of an id
-- id: the id to find
--- return value: the id of the successor, or
-1
if the request failed
+-- 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
function find_successor(id)
if is_in_interval(id, my_node.id + 1, my_node.fingers[1]) then
@@
-214,26
+263,38
@@
function remote_find_successor(ask_to, id)
task.request_id = id
task.answer_to = my_node.id
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
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
while true do
- task =
simgrid.comm.wait(my_node.comm_recv,
timeout)
+ task =
my_node.comm_recv:wait(
timeout)
my_node.comm_recv = simgrid.task.irecv(my_node.id)
if not task then
-- failed to receive the answer
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?
return nil
else
-- a task was received: is it the expected answer?
- if task.type ~= "find successor answer" or task
[request_id]
~= id then
+ if task.type ~= "find successor answer" or task
.request_id
~= id then
-- this is not our answer
-- this is not our answer
+ simgrid.info("Received another request of type " .. task.type)
handle_task(task)
else
-- this is our answer
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
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
return successor
@@
-251,7
+312,7
@@
function remote_get_predecessor(ask_to)
if task:send(ask_to, timeout) then
-- request successfully sent: wait for an answer
while true do
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)
+ task =
my_node.comm_recv:wait(
timeout)
my_node.comm_recv = simgrid.task.irecv(my_node.id)
if not task then
my_node.comm_recv = simgrid.task.irecv(my_node.id)
if not task then
@@
-286,7
+347,7
@@
function stabilize()
end
-- this node is a candidate to become my new successor
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
+ if candidate ~= nil and is_in_interval(candidate, my_node.id + 1, successor -
1) then
my_node.fingers[1] = candidate
end
my_node.fingers[1] = candidate
end
@@
-323,7
+384,7
@@
function fix_fingers()
local id = find_successor(my_node.id + 2^i)
if id ~= nil then
if id ~= my_node.fingers[i] then
local id = find_successor(my_node.id + 2^i)
if id ~= nil then
if id ~= my_node.fingers[i] then
- fingers[i] = id
+
my_node.
fingers[i] = id
end
my_node.next_finger_to_fix = (i % nb_bits) + 1
end
end
my_node.next_finger_to_fix = (i % nb_bits) + 1
end