mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
99 lines
2.2 KiB
Lua
99 lines
2.2 KiB
Lua
--
|
|
-- MODBUS Transaction Controller
|
|
--
|
|
|
|
local util = require("scada-common.util")
|
|
|
|
local txnctrl = {}
|
|
|
|
local TIMEOUT = 2000 -- 2000ms max wait
|
|
|
|
-- create a new transaction controller
|
|
---@nodiscard
|
|
function txnctrl.new()
|
|
local self = {
|
|
list = {},
|
|
next_id = 0
|
|
}
|
|
|
|
---@class transaction_controller
|
|
local public = {}
|
|
|
|
local insert = table.insert
|
|
local remove = table.remove
|
|
|
|
-- get the length of the transaction list
|
|
---@nodiscard
|
|
function public.length()
|
|
return #self.list
|
|
end
|
|
|
|
-- check if there are no active transactions
|
|
---@nodiscard
|
|
function public.empty()
|
|
return #self.list == 0
|
|
end
|
|
|
|
-- create a new transaction of the given type
|
|
---@nodiscard
|
|
---@param txn_type integer
|
|
---@return integer txn_id
|
|
function public.create(txn_type)
|
|
local txn_id = self.next_id
|
|
|
|
insert(self.list, {
|
|
txn_id = txn_id,
|
|
txn_type = txn_type,
|
|
expiry = util.time() + TIMEOUT
|
|
})
|
|
|
|
self.next_id = self.next_id + 1
|
|
|
|
return txn_id
|
|
end
|
|
|
|
-- mark a transaction as resolved to get its transaction type
|
|
---@nodiscard
|
|
---@param txn_id integer
|
|
---@return integer|nil txn_type
|
|
function public.resolve(txn_id)
|
|
local txn_type = nil
|
|
|
|
for i = 1, public.length() do
|
|
if self.list[i].txn_id == txn_id then
|
|
local entry = remove(self.list, i)
|
|
txn_type = entry.txn_type
|
|
break
|
|
end
|
|
end
|
|
|
|
return txn_type
|
|
end
|
|
|
|
-- renew a transaction by re-inserting it with its ID and type
|
|
---@param txn_id integer
|
|
---@param txn_type integer
|
|
function public.renew(txn_id, txn_type)
|
|
insert(self.list, {
|
|
txn_id = txn_id,
|
|
txn_type = txn_type,
|
|
expiry = util.time() + TIMEOUT
|
|
})
|
|
end
|
|
|
|
-- close timed-out transactions
|
|
function public.cleanup()
|
|
local now = util.time()
|
|
util.filter_table(self.list, function (txn) return txn.expiry > now end)
|
|
end
|
|
|
|
-- clear the transaction list
|
|
function public.clear()
|
|
self.list = {}
|
|
end
|
|
|
|
return public
|
|
end
|
|
|
|
return txnctrl
|