Add get and pull

Signed-off-by: Rahix <rahix@rahix.de>
dev
rahix 7 years ago
parent 7063e7445d
commit da6c36922b

@ -251,5 +251,11 @@ serialized using `OpenOS`'s `serialization` library.
### `Network:broadcast(msg_tbl)`
Send a message to all connected nodes on the network.
### `Network:pull(filter_func, timeout)`
Block until a message arrives for which `filter_func` returns `true`. The signature
of `filter_func` is `function(addr, msg_tbl)`, similar to the callback given to
`Network:start`. If `timeout` is not `nil`, `pull` should return after the
timeout expired as well.
### `Network:stop()`
Close this connection and uninstall the message handler.

@ -216,4 +216,14 @@ function test_multinode_iters()
assert_equal("miter2v", verbs[1], "verb-list incorrect")
assert_equal("miter4v", verbs[2], "verb-list incorrect")
end
function test_get_network()
local bc1 = BaseControl:new()
bc1:register("getnw1", 123)
bc1:finalize()
local bc2 = BaseControl:new()
assert_equal(123, bc2:get("getnw1"), "wrong value")
end
-- }}}

@ -41,6 +41,7 @@ function Network:new(modem, port)
local self = {
modem = modem or require("component").modem,
port = port or Network.default_port,
event = require("event"),
}
setmetatable(self, {__index=Network})
@ -56,7 +57,7 @@ function Network:start(callback)
if port ~= self.port then return end
callback(addr_remote, serialization.unserialize(msg))
end
require("event").listen("modem_message", self.listener)
self.event.listen("modem_message", self.listener)
end
function Network:send(addr, msg)
@ -67,8 +68,24 @@ function Network:broadcast(msg)
self.modem.broadcast(self.port, serialization.serialize(msg))
end
function Network:pull(filter, timeout)
local last_msg
local ev = self.event.pullFiltered(timeout, function(ev, addr_lo, addr_remote, port, _, msg)
if ev ~= "modem_message" then return false end
if addr_lo ~= self.modem.address then return false end
if port ~= self.port then return false end
last_msg = serialization.unserialize(msg)
return filter(addr_remote, last_msg)
end)
if ev ~= "nil" then
return last_msg
else
return nil, "timeout"
end
end
function Network:stop()
require("event").ignore("modem_message", self.listener)
self.event.ignore("modem_message", self.listener)
self.modem.close(self.port)
end
-- }}}
@ -163,8 +180,23 @@ function BaseControl:get(noun, timeout)
return self.local_nouns[noun]
elseif self.local_verbs[noun] ~= nil then
error("\""..noun.."\" is not a noun")
elseif self.remote_nouns[noun] ~= nil then
self.network:send(self.remote_nouns[noun], {
ty=Message.NounRequest,
noun=noun,
})
local answer, err = self.network:pull(function(remote, msg)
if remote ~= self.remote_nouns[noun] then return false end
if msg.ty ~= Message.NounResponse then return false end
if msg.noun ~= noun then return false end
end, timeout)
if answer == nil then
return nil, err
else
return answer.value
end
else
return nil
return nil, "noun \""..noun.."\" unknown"
end
end
@ -232,8 +264,16 @@ function BaseControl:_network_handler(remote, msg)
for _, verb in ipairs(msg.verbs or {}) do
self.remote_verbs[verb] = remote
end
elseif msg.ty == Message.NounRequest then
self.network:send(remote, {
ty=Message.NounResponse,
noun=msg.noun,
value=self.local_nouns[msg.noun],
})
elseif msg.ty == Message.NounResponse then
-- Handled via pull
else
error("TODO: Delet this")
error("TODO: MessageType Unknown")
end
end
-- }}}

Loading…
Cancel
Save