Skip to content

Commit d3a8ef6

Browse files
committedJul 31, 2024
fix(handlers): create a handler factory for action
1 parent 2856fda commit d3a8ef6

File tree

2 files changed

+96
-102
lines changed

2 files changed

+96
-102
lines changed
 

‎src/common/main.lua

+89-95
Original file line numberDiff line numberDiff line change
@@ -11,128 +11,122 @@ local function errorHandler(err)
1111
end
1212

1313
main.init = function()
14-
ANTS = ANTS or {}
1514
-- Example ANT structure
1615
-- ANTS["antId"] = {
1716
-- Owner = "userId",
1817
-- Controllers = {"userId1", "userId2"},
1918
-- }
20-
USERS = USERS or {}
21-
-- Example USERS structure
22-
-- USERS["userId"] = {"antId1", "antId2"}
19+
ANTS = ANTS or {}
20+
21+
-- Example ADDRESSES structure - keyed references to the above ANTS structure
22+
-- ADDRESSES["userAddress"] = {["antProcessId1"] = ANTS["antProcessId1"], ANTS["antProcessId2"]}
23+
ADDRESSES = ADDRESSES or {}
24+
25+
--[[
26+
position defaults to "add"
27+
28+
Behavior:
29+
- "add" - Adds the handler to the end of the list
30+
- "prepend" - Adds the handler to the beginning of the list
31+
- "append" - Adds the handler to the end of the list
32+
33+
create a handler by matching an action name to an Action tag on the message
34+
if the handler function throws an error, send an error message to the sender
35+
36+
]]
37+
local function createActionHandler(action, msgHandler, position)
38+
assert(type(position) == "string" or type(position) == "nil", errorHandler("Position must be a string or nil"))
39+
assert(
40+
position == nil or position == "add" or position == "prepend" or position == "append",
41+
"Position must be one of 'add', 'prepend', 'append'"
42+
)
43+
return Handlers[position or "add"](camel(action), Handlers.utils.hasMatchingTag("Action", action), function(msg)
44+
print("Handling Action [" .. msg.Id .. "]: " .. action)
45+
local handlerStatus, handlerRes = xpcall(function()
46+
msgHandler(msg)
47+
end, errorHandler)
48+
49+
if not handlerStatus then
50+
ao.send({
51+
Target = msg.From,
52+
Action = "Invalid-" .. action .. "-Notice",
53+
Error = action .. "-Error",
54+
["Message-Id"] = msg.Id,
55+
Data = handlerRes,
56+
})
57+
end
58+
59+
return handlerRes
60+
end)
61+
end
2362

2463
local ActionMap = {
2564
Register = "Register",
2665
StateNotice = "State-Notice",
2766
AccessControlList = "Access-Control-List",
2867
}
2968

30-
Handlers.add(camel(ActionMap.Register), Handlers.utils.hasMatchingTag("Action", ActionMap.Register), function(msg)
31-
print("Action: " .. ActionMap.Register)
32-
69+
createActionHandler(ActionMap.Register, function(msg)
3370
local antId = msg.Tags["Process-Id"]
3471
assert(type(antId) == "string", "Process-Id tag is required")
72+
assert(ANTS[antId] == nil, "ANT is already registered")
73+
74+
ANTS[antId] = {
75+
Owner = nil,
76+
Controllers = {},
77+
}
78+
79+
ao.send({
80+
Target = antId,
81+
Action = "State",
82+
})
83+
ao.send({
84+
Target = msg.From,
85+
Action = "Register-Notice",
86+
})
87+
end)
3588

36-
if ANTS[antId] then
37-
ao.send({
38-
Target = msg.From,
39-
Action = "Register-Notice-Failure",
40-
["Message-Id"] = msg.Id,
41-
Data = "ANT is already registered",
42-
})
43-
else
44-
ANTS[antId] = {
45-
Owner = nil,
89+
createActionHandler(ActionMap.StateNotice, function(msg)
90+
local stateRes = utils.parseAntState(msg.Data)
91+
-- Check if already registered
92+
local isRegistered = ANTS[msg.From] ~= nil
93+
94+
-- Register the ANT if not already registered
95+
if not isRegistered then
96+
ANTS[msg.From] = {
97+
Owner = stateRes.Owner,
4698
Controllers = {},
99+
-- for cleaning function
100+
RegisteredAt = tonumber(msg.Timestamp),
47101
}
102+
end
48103

49-
ao.send({
50-
Target = antId,
51-
Action = "State",
52-
})
104+
utils.updateAssociations(msg.From, stateRes)
105+
106+
-- Notify the ANT that it has been registered
107+
if not isRegistered then
53108
ao.send({
54109
Target = msg.From,
55110
Action = "Register-Notice",
111+
["Message-Id"] = msg.Id,
56112
})
57113
end
58114
end)
59115

60-
Handlers.add(
61-
camel(ActionMap.StateNotice),
62-
Handlers.utils.hasMatchingTag("Action", ActionMap.StateNotice),
63-
function(msg)
64-
print("Action: " .. ActionMap.StateNotice)
65-
66-
local stateStatus, stateRes = xpcall(function()
67-
return utils.parseAntState(msg.Data)
68-
end, errorHandler)
69-
if not stateStatus then
70-
ao.send({
71-
Target = msg.From,
72-
Action = "State-Notice-Failure",
73-
["Message-Id"] = msg.Id,
74-
Data = tostring(stateRes),
75-
})
76-
return
77-
end
78-
79-
-- Check if already registered
80-
local isRegistered = ANTS[msg.From] ~= nil
81-
82-
-- Register the ANT if not already registered
83-
if not isRegistered then
84-
ANTS[msg.From] = {
85-
Owner = stateRes.Owner,
86-
Controllers = {},
87-
-- for cleaning function
88-
RegisteredAt = tonumber(msg.Timestamp),
89-
}
90-
end
116+
createActionHandler(ActionMap.AccessControlList, function(msg)
117+
local address = msg.Tags["Address"]
118+
assert(type(address) == "string", "Address is required")
91119

92-
local aclUpdateStatus, aclUpdateRes = xpcall(function()
93-
return utils.updateAssociations(msg.From, stateRes)
94-
end, errorHandler)
95-
if not aclUpdateStatus then
96-
ao.send({
97-
Target = msg.From,
98-
Action = "State-Notice-Failure",
99-
["Message-Id"] = msg.Id,
100-
Data = aclUpdateRes,
101-
})
102-
return
103-
end
120+
local antIds = ADDRESSES[address] or {}
104121

105-
-- Notify the ANT that it has been registered
106-
if not isRegistered then
107-
ao.send({
108-
Target = msg.From,
109-
Action = "Register-Notice",
110-
["Message-Id"] = msg.Id,
111-
})
112-
end
113-
end
114-
)
115-
116-
Handlers.add(
117-
camel(ActionMap.AccessControlList),
118-
Handlers.utils.hasMatchingTag("Action", ActionMap.AccessControlList),
119-
function(msg)
120-
print("Action: " .. ActionMap.AccessControlList)
121-
122-
local address = msg.Tags["Address"]
123-
assert(type(address) == "string", "Address is required")
124-
125-
local antIds = USERS[address] or {}
126-
127-
-- Send the list of ant_ids as a JSON array
128-
ao.send({
129-
Target = msg.From,
130-
Action = "Access-Control-List-Notice",
131-
["Message-Id"] = msg.Id,
132-
Data = json.encode(antIds),
133-
})
134-
end
135-
)
122+
-- Send the list of ant_ids as a JSON array
123+
ao.send({
124+
Target = msg.From,
125+
Action = "Access-Control-List-Notice",
126+
["Message-Id"] = msg.Id,
127+
Data = json.encode(antIds),
128+
})
129+
end)
136130

137131
Handlers.prepend("cleanOldRegistrations", function(msg)
138132
return "continue"

‎src/common/utils.lua

+7-7
Original file line numberDiff line numberDiff line change
@@ -244,20 +244,20 @@ end
244244

245245
function utils.updateUserAssociations(antId, state, user)
246246
-- remove previous associations
247-
if USERS[user] and user ~= state.Owner and not utils.includes(user, state.Controllers) then
248-
local antIndex = utils.indexOf(USERS[user], antId)
247+
if ADDRESSES[user] and user ~= state.Owner and not utils.includes(user, state.Controllers) then
248+
local antIndex = utils.indexOf(ADDRESSES[user], antId)
249249
if antIndex then
250-
table.remove(USERS[user], antIndex)
250+
table.remove(ADDRESSES[user], antIndex)
251251
end
252252
end
253253

254254
-- add new associations
255255
if user == state.Owner or utils.includes(user, state.Controllers) then
256-
if not USERS[user] then
257-
USERS[user] = {}
256+
if not ADDRESSES[user] then
257+
ADDRESSES[user] = {}
258258
end
259-
if not utils.includes(antId, USERS[user]) then
260-
table.insert(USERS[user], antId)
259+
if not utils.includes(antId, ADDRESSES[user]) then
260+
table.insert(ADDRESSES[user], antId)
261261
end
262262
end
263263
end

0 commit comments

Comments
 (0)