-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomessage.lua
More file actions
80 lines (69 loc) · 2.06 KB
/
comessage.lua
File metadata and controls
80 lines (69 loc) · 2.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
local socket = require("socket")
local string = require("string")
local table = require("table")
local coroutine = require("coroutine")
local coscheduler = require("coscheduler")
local coutils = require("coutils")
local os = os
local ipairs = ipairs
local pairs = pairs
local assert = assert
local print = print
local type = type
local tostring = tostring
local setmetatable = setmetatable
local base = _G
module("comessage")
local log = coutils.new_logger(coutils.INFO)
local messages = {} -- map: (receiver_id, msg)
local suspent_coroutines = {} -- map: (id, co)
local Mailbox = {} -- the table representing the class, which will double as the metatable for the instances
--Mailbox.__index = Mailbox -- failed table lookups on the instances should fallback to the class table, to get methods
local function new_message(sender_id, body)
self = {}
self.sender_id = sender_id
self.body = body
return self
end
function new_mailbox(my_id)
local self = setmetatable({}, {__index=Mailbox})
assert(my_id ~= nil)
self.id = my_id
return self
end
function Mailbox:sendto(receiver_id, msg_body)
log:debug({sendto=self})
local _msg = new_message(self.id, msg_body)
assert(receiver_id ~= nil and msg_body ~= nil)
if messages[ receiver_id] == nil then
messages[ receiver_id] = { _msg }
else
table.insert(messages[ receiver_id], _msg)
end
-- will suspend until receiver get the message
end
function Mailbox:receive()
log:debug("receive was call, myid="..(self.id or "nil"))
suspent_coroutines[ self.id ] = coroutine.running()
local sender_id, msg = coroutine.yield()
return sender_id, msg
--suspent_coroutines
end
local function step_scheduler()
local rc = false
for receiver_id, co in pairs(suspent_coroutines) do
local mailbox = messages[receiver_id]
if (mailbox ~= nil) then
local msg = mailbox[1]
log:debug({msg=msg})
table.remove(mailbox, 1)
if (#mailbox == 0) then
messages[receiver_id] = nil
end
coroutine.resume(co, msg.sender_id, msg.body)
rc = true
end
end
return rc
end
coscheduler.register_step_scheduler("comessage", step_scheduler)