Removed extra bloat, proxies are portable now!

This commit is contained in:
2023-06-25 21:46:37 -04:00
parent c39aa229f8
commit 660c10ec3b
13 changed files with 293 additions and 374 deletions
+71 -244
View File
@@ -22,8 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
function copy(obj)
if type(obj) ~= 'table' then return obj end
local function copy(obj)
if type(obj) ~= 'table' then return obj end
local res = {}
for k, v in pairs(obj) do res[copy(k)] = copy(v) end
return res
@@ -48,34 +48,19 @@ local multi, thread = require("multi"):init()
-- Create on the thread that you want to interact with, send over the handle
function multi:chop(obj)
if not _G["UIDS"] then
_G["UIDS"] = {}
end
local multi, thread = require("multi"):init()
local list = {[0] = multi.randomString(12)}
_G[list[0]] = obj
for i,v in pairs(obj) do
if type(v) == "function" then
if type(v) == "function" or type(v) == "table" and v.Type == multi.THREADEDFUNCTION then
table.insert(list, i)
elseif type(v) == "table" and v.Type == multi.CONNECTOR then
v.getThreadID = function() -- Special function we are adding
return THREAD_ID
end
v.getUniqueName = function(self)
return self.__link_name
end
local l = multi:chop(v)
v.__link_name = l[0]
v.__name = i
table.insert(list, {i, multi:newProxy(l):init()})
elseif type(v) == "table" and v.Type == multi.CONNECTOR then
table.insert(list, {i, multi:newProxy(multi:chop(v)):init()})
end
end
table.insert(list, "isConnection")
if obj.Type == multi.CONNECTOR then
obj.isConnection = function() return true end
else
obj.isConnection = function() return false end
end
return list
end
@@ -85,44 +70,63 @@ function multi:newProxy(list)
c.name = multi.randomString(12)
c.is_init = false
function c:init(proc_name)
local multi, thread = nil, nil
function c:init()
local multi, thread = nil, nil
if not(c.is_init) then
c.is_init = true
local multi, thread = require("multi"):init()
c.proxy_link = "PL" .. multi.randomString(12)
if multi.integration then
GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD
end
GLOBAL[c.proxy_link] = c
local function check()
return self.send:pop()
end
self.send = multi:newSystemThreadedQueue(self.name.."_S"):init()
self.recv = multi:newSystemThreadedQueue(self.name.."_R"):init()
self.funcs = list
self._funcs = copy(list)
self.Type = multi.PROXY
self.TID = THREAD_ID
thread:newThread(function()
thread:newThread("Proxy_Handler_" .. multi.randomString(4), function()
while true do
local data = thread.hold(check)
if data then
local func = table.remove(data, 1)
local sref = table.remove(data, 1)
local ret
if sref then
ret = {_G[list[0]][func](_G[list[0]], multi.unpack(data))}
else
ret = {_G[list[0]][func](multi.unpack(data))}
end
for i = 1,#ret do
if type(ret[i]) == "table" and getmetatable(ret[i]) then
setmetatable(ret[i],{}) -- remove that metatable, we do not need it on the other side!
-- Let's not hold the main threadloop
thread:newThread("Temp_Thread", function()
local func = table.remove(data, 1)
local sref = table.remove(data, 1)
local ret
if sref then
ret = {_G[list[0]][func](_G[list[0]], multi.unpack(data))}
else
ret = {_G[list[0]][func](multi.unpack(data))}
end
if ret[i] == _G[list[0]] then
-- We cannot return itself, that return can contain bad values.
ret[i] = {_self_ref_ = true}
for i = 1,#ret do
if type(ret[i]) == "table" and ret[i].Type ~= nil and ret[i].Type ~= multi.PROXY then
ret[i] = "\1PARENT_REF"
end
if type(ret[i]) == "table" and getmetatable(ret[i]) then
setmetatable(ret[i],nil) -- remove that metatable, we do not need it on the other side!
end
if ret[i] == _G[list[0]] then
-- We cannot return itself, that return can contain bad values.
ret[i] = "\1SELF_REF"
end
end
end
table.insert(ret, 1, func)
self.recv:push(ret)
table.insert(ret, 1, func)
self.recv:push(ret)
end)
end
end
end).OnError(multi.error)
@@ -130,7 +134,7 @@ function multi:newProxy(list)
else
local multi, thread = require("multi"):init()
local me = self
self.proc_name = proc_name
local funcs = copy(self.funcs)
if multi.integration then
GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD
@@ -138,21 +142,13 @@ function multi:newProxy(list)
self.send = THREAD.waitFor(self.name.."_S"):init()
self.recv = THREAD.waitFor(self.name.."_R"):init()
self.Type = multi.PROXY
for _,v in pairs(self.funcs) do
for _,v in pairs(funcs) do
if type(v) == "table" then
-- We have a connection
v[2]:init(proc_name)
self["_"..v[1]] = v[2]
self[v[1]] = v[2]
v[2].Parent = self
setmetatable(v[2],getmetatable(multi:newConnection()))
self[v[1]] = multi:newConnection()
thread:newThread(function()
while true do
local data = thread.hold(self["_"..v[1]])
self[v[1]]:Fire(data)
end
end).OnError(multi.error)
else
self[v] = thread:newFunction(function(self,...)
if self == me then
@@ -166,8 +162,10 @@ function multi:newProxy(list)
me.recv:pop()
table.remove(data, 1)
for i=1,#data do
if type(data[i]) == "table" and data[i]._self_ref_ then
if data[i] == "\1SELF_REF" then
data[i] = me
elseif data[i] == "\1PARENT_REF" then
data[i] = me.Parent
end
end
return multi.unpack(data)
@@ -180,85 +178,31 @@ function multi:newProxy(list)
end
end
function c:getTransferable()
local multi, thread = nil, nil
local cp = {}
local multi, thread = require("multi"):init()
cp.is_init = true
cp.proxy_link = self.proxy_link
cp.name = self.name
cp.funcs = copy(self._funcs)
cp._funcs = copy(self._funcs)
cp.Type = self.Type
cp.init = self.init
cp.init = function(self)
local multi, thread = require("multi"):init()
if multi.integration then
GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD
end
local proxy = THREAD.waitFor(self.proxy_link)
proxy.funcs = self.funcs
return proxy:init()
end
return cp
end
self:create(c)
return c
end
local targets = {}
local references = {}
local nFunc = 0
function multi:newTargetedFunction(ID, proxy, name, func, holup) -- This registers with the queue
if type(name)=="function" then
holup = func
func = name
name = "JQ_TFunc_"..nFunc
end
nFunc = nFunc + 1
multi:executeOnProcess(proxy.proc_name, function(proc, name, func)
proc.jobqueue:registerFunction(name, func)
end, name, func)
return thread:newFunction(function(...)
return multi:executeOnProcess(proxy.proc_name, function(proc, name, ID, ...)
local multi, thread = require("multi"):init()
local id = proc:pushJob(ID, name, ...)
local rets
local tjq = THREAD.get(proc.Name .. "_target_rtq_" .. ID):init()
return thread.hold(function()
local data = tjq:peek()
if data and data[1] == id then
tjq:pop()
table.remove(data, 1)
return multi.unpack(data) or multi.NIL
end
end)
-- proc.jobqueue.OnJobCompleted(function(jid, ...)
-- if id==jid then
-- rets = {...}
-- print("Got!")
-- end
-- end)
-- return thread.hold(function()
-- if rets then
-- return multi.unpack(rets) or multi.NIL
-- end
-- end)
end, name, ID, ...)
end, holup), name
end
multi.executeOnProcess = thread:newFunction(function(self, name, func, ...)
local queue = THREAD.get(name .. "_local_proc")
local queueR = THREAD.get(name .. "_local_return")
if queue and queueR then
local multi, thread = require("multi"):init()
local id = multi.randomString(8)
queue = queue:init()
queueR = queueR:init()
queue:push({func, id, ...})
return thread.hold(function()
local data = queueR:peek()
if data and data[1] == id then
queueR:pop()
table.remove(data, 1)
return multi.unpack(data) or multi.NIL
end
end)
else
return nil, "Unable to find a process queue with name: '" .. name .. "'"
end
end, true)
local jid = -1
function multi:newSystemThreadedProcessor(cores)
@@ -279,69 +223,16 @@ function multi:newSystemThreadedProcessor(cores)
c.OnObjectCreated = multi:newConnection()
c.parent = self
c.jobqueue = multi:newSystemThreadedJobQueue(c.cores)
c.local_cmd = multi:newSystemThreadedQueue(name .. "_local_proc"):init()
c.local_cmd_return = multi:newSystemThreadedQueue(name .. "_local_return"):init()
c.jobqueue:registerFunction("STP_enable_targets",function(name)
local multi, thread = require("multi"):init()
local qname = name .. "_tq_" .. THREAD_ID
local rqname = name .. "_rtq_" .. THREAD_ID
local tjq = multi:newSystemThreadedQueue(qname):init()
local trq = multi:newSystemThreadedQueue(rqname):init()
multi:newThread("TargetedJobHandler", function()
local th
while true do
local dat = thread.hold(function()
return tjq:pop()
end)
if dat then
th = thread:newThread("JQ-TargetThread",function()
local name = table.remove(dat, 1)
local jid = table.remove(dat, 1)
local func = _G[name]
local args = table.remove(dat, 1)
th.OnError(function(self,err)
-- We want to pass this to the other calling thread incase
trq:push{jid, err}
end)
trq:push{jid, func(multi.unpack(args))}
end)
end
end
end).OnError(multi.error)
end)
c.jobqueue:registerFunction("STP_GetThreadCount",function()
return _G["__THREADS"]
end)
c.jobqueue:registerFunction("STP_GetTaskCount",function()
return _G["__TASKS"]
end)
function c:pushJob(ID, name, ...)
local tq = THREAD.waitFor(self.Name .. "_target_tq_" .. ID):init()
tq:push{name, jid, {...}}
tq:push{name, jid, multi.pack(...)}
jid = jid - 1
return jid + 1
end
c.jobqueue:doToAll(function(name)
STP_enable_targets(name)
_G["__THREADS"] = 0
_G["__TASKS"] = 0
end, name.."_target")
c.jobqueue:registerFunction("packObj",function(obj)
local multi, thread = require("multi"):init()
obj.getThreadID = function() -- Special functions we are adding
return THREAD_ID
end
obj.getUniqueName = function(self)
return self.__link_name
end
local list = multi:chop(obj)
obj.__link_name = list[0]
@@ -354,14 +245,12 @@ function multi:newSystemThreadedProcessor(cores)
c.spawnThread = c.jobqueue:newFunction("__spawnThread__", function(name, func, ...)
local multi, thread = require("multi"):init()
local obj = thread:newThread(name, func, ...)
_G["__THREADS"] = _G["__THREADS"] + 1
return packObj(obj)
end, true)
c.spawnTask = c.jobqueue:newFunction("__spawnTask__", function(obj, func, ...)
local multi, thread = require("multi"):init()
local obj = multi[obj](multi, func, ...)
_G["__TASKS"] = _G["__TASKS"] + 1
return packObj(obj)
end, true)
@@ -372,12 +261,13 @@ function multi:newSystemThreadedProcessor(cores)
"newEvent",
"newAlarm",
"newStep",
"newTStep"
"newTStep",
"newService"
}
for _, method in pairs(implement) do
c[method] = function(self, ...)
proxy = self.spawnTask(method, ...):init(self.Name)
proxy = self.spawnTask(method, ...):init()
references[proxy] = self
return proxy
end
@@ -467,68 +357,5 @@ function multi:newSystemThreadedProcessor(cores)
return loads
end, true)
local check = function()
return c.local_cmd:pop()
end
thread:newThread(function()
while true do
local data = thread.hold(check)
if data then
thread:newThread(function()
local func = table.remove(data, 1)
local id = table.remove(data, 1)
local ret = {id, func(c, multi.unpack(data))}
c.local_cmd_return:push(ret)
end).OnError(multi.error)
end
end
end).OnError(multi.error)
return c
end
-- Modify thread.hold to handle proxies
local thread_ref = thread.hold
function thread.hold(n, opt)
if type(n) == "table" and n.Type == multi.PROXY and n.isConnection() then
local ready = false
local args
local id = n.getThreadID()
local name = n:getUniqueName()
local func = multi:newTargetedFunction(id, n, "conn_"..multi.randomString(8), function(_name)
local multi, thread = require("multi"):init()
local obj = _G[_name]
local rets = {thread.hold(obj)}
for i,v in pairs(rets) do
if v.Type then
rets[i] = {_self_ref_ = "parent"}
end
end
return multi.unpack(rets)
end)
local conn
local args
handle = func(name)
conn = handle.OnReturn(function(...)
ready = true
args = {...}
handle.OnReturn:Unconnect(conn)
end)
local ret = {thread_ref(function()
if ready then
return multi.unpack(args) or multi.NIL
end
end, opt)}
for i,v in pairs(ret) do
if type(v) == "table" and v._self_ref_ == "parent" then
ret[i] = n.Parent
end
end
return multi.unpack(ret)
else
return thread_ref(n, opt)
end
end