From 20647f47388185785174bf3d4f1632205abcede6 Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Fri, 1 Feb 2019 10:43:00 -0500 Subject: [PATCH] more updates --- changes.md | 2 + multi/init.lua | 72 +++++++++++++++----------- multi/integration/networkManager.lua | 27 ++++------ test.lua | 76 ++++++++++++---------------- 4 files changed, 88 insertions(+), 89 deletions(-) diff --git a/changes.md b/changes.md index d880d4d..6c69832 100644 --- a/changes.md +++ b/changes.md @@ -54,6 +54,8 @@ Fixed: - Found an issue with the rockspec which is due to the networkManager additon. The net Library and the multi Library are now codependent if using that feature. Going forward you will have to now install the network library separately - Insane proformance bug found in the networkManager file, where each connection to a node created a new thread (VERY BAD) If say you connected to 100s of threads, you would lose a lot of processing power due to a bad implementation of this feature. But it goes futhur than this, the net library also creates a new thread for each connection made, so times that initial 100 by about 3, you end up with a system that quickly eats itself. I have to do tons of rewriting of everything. Yet another setback for the 13.0.0 release - Fixed an issue where any argument greater than 256^2/65536 bytes is sent the networkmanager would soft crash. This was fixed by increading the limit to 256^4/4294967296 bytes. The fix was changing a 2 to a 4. Arguments greater than 256^4 would be impossible in 32 bit lua, and highly unlikely even in lua 64 bit. Perhaps someone is reading an entire file into ram and then sending the entire file that they read over a socket for some reason all at once!? +- Fixed an issue with processors not properly destroying objects within them and not being destroyable themselves +- Fixed a bug where pause and resume would duplicate objects! Not good Added: - Documentation, the purpose of 13.0.0, orginally going to be 12.2.3, but due to the amount of bugs and features I added couldn't become that. I actually still did my tests in the 12.2.3 branch in github. diff --git a/multi/init.lua b/multi/init.lua index d6bdd29..dde3b0b 100644 --- a/multi/init.lua +++ b/multi/init.lua @@ -34,7 +34,6 @@ multi.ender = {} multi.Children = {} multi.Active = true multi.fps = 60 -multi.Id = -1 multi.Type = "mainprocess" multi.Rest = 0 multi._type = type @@ -138,7 +137,7 @@ function multi:enableLoadDetection() while not stop do temp:uManager() end - temp:__Destroy() + temp:Destroy() multi.maxSpd = stop end local MaxLoad = nil @@ -335,19 +334,28 @@ function multi:getTasksDetails(t) str = { {"Type","Uptime","Priority","TID"} } + local count = 0 for i,v in pairs(self.Mainloop) do local name = v.Name or "" if name~="" then name = " <"..name..">" end + count = count + 1 table.insert(str,{v.Type:sub(1,1):upper()..v.Type:sub(2,-1)..name,multi.Round(os.clock()-v.creationTime,3),self.PriorityResolve[v.Priority],i}) end + if count == 0 then + table.insert(str,{"Currently no processes running!","","",""}) + end local s = multi.AlignTable(str) dat = "" - for i=1,#multi.scheduler.Threads do - dat = dat .. "\n" + if multi.scheduler then + for i=1,#multi.scheduler.Threads do + dat = dat .. "\n" + end + return "Load on "..({[true]="SubProcess<"..(self.Name or "Unnamed")..">",[false]="MainProcess"})[self.Type=="process"]..": "..multi.Round(multi:getLoad(),2).."%\nMemory Usage: "..math.ceil(collectgarbage("count")).." KB\nThreads Running: "..#multi.scheduler.Threads.."\n\n"..s.."\n\n"..dat + else + return "Load on "..({[true]="SubProcess<"..(self.Name or "Unnamed")..">",[false]="MainProcess"})[self.Type=="process"]..": "..multi.Round(multi:getLoad(),2).."%\nMemory Usage: "..math.ceil(collectgarbage("count")).." KB\nThreads Running: 0\n\n"..s end - return "Load on manager: "..multi.Round(multi:getLoad(),2).."%\nMemory Usage: "..math.ceil(collectgarbage("count")).." KB\nThreads Running: "..#multi.scheduler.Threads.."\n\n"..s.."\n\n"..dat elseif t == "t" or t == "table" then str = {ThreadCount = #multi.scheduler.Threads,MemoryUsage = math.ceil(collectgarbage("count")).." KB"} str.threads = {} @@ -503,8 +511,12 @@ function multi:Pause() print("You cannot pause the main process. Doing so will stop all methods and freeze your program! However if you still want to use multi:_Pause()") else self.Active=false - if self.Parent.Mainloop[self.Id]~=nil then - table.remove(self.Parent.Mainloop,self.Id) + local loop = self.Parent.Mainloop + for i=1,#loop do + if loop[i] == self then + table.remove(loop,i) + break + end end end return self @@ -517,9 +529,8 @@ function multi:Resume() c[i]:Resume() end else - if self:isPaused() then + if self.Active==false then table.insert(self.Parent.Mainloop,self) - self.Id=#self.Parent.Mainloop self.Active=true end end @@ -556,8 +567,10 @@ function multi:create(ref) multi.OnObjectCreated:Fire(ref,self) end function multi:setName(name) - self.Name = name - end + self.Name = name + return self +end +multi.SetName = multi.setName --Constructors [CORE] function multi:newBase(ins) if not(self.Type=='mainprocess' or self.Type=='process' or self.Type=='queue') then error('Can only create an object on multi or an interface obj') return false end @@ -573,7 +586,6 @@ function multi:newBase(ins) c.funcTMR={} c.ender={} c.important={} - c.Id=0 c.Act=function() end c.Parent=self c.held=false @@ -597,7 +609,6 @@ function multi:newProcessor(file) c.Garbage={} c.Children={} c.Active=false - c.Id=-1 c.Rest=0 c.Jobs={} c.queue={} @@ -621,7 +632,8 @@ function multi:newProcessor(file) return self end function c:setName(name) - c.Name = name + c.l.Name = name + return self end function c:Pause() if self.l then @@ -637,6 +649,18 @@ function multi:newProcessor(file) self:__Destroy() end end + function c:Destroy() + if self == c then + self.l:Destroy() + else + for i = #c.Mainloop,1,-1 do + if c.Mainloop[i] == self then + table.remove(c.Mainloop,i) + break + end + end + end + end if file then self.Cself=c loadstring('local process=multi.Cself '..io.open(file,'rb'):read('*all'))() @@ -836,7 +860,6 @@ function multi:newJob(func,name) end c.Active=true c.func={} - c.Id=0 c.Parent=self c.Type='job' c.trigfunc=func or function() end @@ -1578,7 +1601,6 @@ function multi:newThreadedProcess(name) ct.Active=true ct.func={} ct.ender={} - ct.Id=0 ct.Act=function() end ct.Parent=self ct.held=false @@ -1589,13 +1611,11 @@ function multi:newThreadedProcess(name) c.Parent=self c.Active=true c.func={} - c.Id=0 c.Type='threadedprocess' c.Mainloop={} c.Garbage={} c.Children={} c.Active=true - c.Id=-1 c.Rest=0 c.updaterate=.01 c.restRate=.1 @@ -1664,7 +1684,6 @@ function multi:newHyperThreadedProcess(name) ct.Active=true ct.func={} ct.ender={} - ct.Id=0 ct.Act=function() end ct.Parent=self ct.held=false @@ -1689,13 +1708,11 @@ function multi:newHyperThreadedProcess(name) c.Parent=self c.Active=true c.func={} - c.Id=0 c.Type='hyperthreadedprocess' c.Mainloop={} c.Garbage={} c.Children={} c.Active=true - c.Id=-1 c.Rest=0 c.updaterate=.01 c.restRate=.1 @@ -2052,11 +2069,12 @@ function multi:uManager(settings) end function multi:uManagerRef(settings) if self.Active then - if ncount ~= 0 then - for i = 1, ncount do - next[i]() + if next then + local DD = table.remove(next,1) + while DD do + DD() + DD = table.remove(next,1) end - ncount = 0 end local Loop=self.Mainloop local PS=self @@ -2236,8 +2254,6 @@ function multi:ToString() important=self.important, Active=self.Active, ender=self.ender, - -- IDK if these need to be present... - -- Id=self.Id, held=self.held, } else @@ -2248,8 +2264,6 @@ function multi:ToString() funcTMR=self.funcTMR, important=self.important, ender=self.ender, - -- IDK if these need to be present... - -- Id=self.Id, held=self.held, } end diff --git a/multi/integration/networkManager.lua b/multi/integration/networkManager.lua index b9e65be..10ea9a8 100644 --- a/multi/integration/networkManager.lua +++ b/multi/integration/networkManager.lua @@ -42,6 +42,7 @@ local CMD_CONSOLE = 0x0B local char = string.char local byte = string.byte +-- Process to hold all of the networkManager's muilt objects -- Helper for piecing commands local function pieceCommand(cmd,...) @@ -440,14 +441,11 @@ function multi:newMaster(settings) -- You will be able to have more than one mas name = self:getRandomNode() end if name==nil then - multi:newThread("Network Thread Manager",function(loop) - while true do - if name~=nil then - self:sendTo(name,char(CMD_TASK)..len..aData..len2..fData) - thread.kill() - end - thread.sleep(.1) - end + multi:newEvent(function() return name~=nil end):OnEvent(function(evnt) + self:sendTo(name,char(CMD_TASK)..len..aData..len2..fData) + evnt:Destroy() + end):SetName("DelayedSendTask"):SetName("DelayedSendTask"):SetTime(8):OnTimedOut(function(self) + self:Destroy() end) else self:sendTo(name,char(CMD_TASK)..len..aData..len2..fData) @@ -462,14 +460,11 @@ function multi:newMaster(settings) -- You will be able to have more than one mas name = "NODE_"..name end if self.connections[name]==nil then - multi:newThread("Node Data Link Controller",function(loop) - while true do - if self.connections[name]~=nil then - self.connections[name]:send(data) - thread.kill() - end - thread.sleep(.1) - end + multi:newEvent(function() return self.connections[name]~=nil end):OnEvent(function(evnt) + self.connections[name]:send(data) + evnt:Destroy() + end):SetName("DelayedSendTask"):SetTime(8):OnTimedOut(function(self) + self:Destroy() end) else self.connections[name]:send(data) diff --git a/test.lua b/test.lua index 4c2bca3..b8bf1fd 100644 --- a/test.lua +++ b/test.lua @@ -1,52 +1,40 @@ package.path="?/init.lua;?.lua;"..package.path multi = require("multi") ---~ local GLOBAL,THREAD = require("multi.integration.lanesManager").init() ---~ nGLOBAL = require("multi.integration.networkManager").init() ---~ local a ---~ function multi:setName(name) ---~ self.Name = name ---~ end ---~ local clock = os.clock ---~ function sleep(n) -- seconds ---~ local t0 = clock() ---~ while clock() - t0 <= n do end ---~ end ---~ master = multi:newMaster{ ---~ name = "Main", -- the name of the master ---~ --noBroadCast = true, -- if using the node manager, set this to true to avoid double connections ---~ managerDetails = {"192.168.1.4",12345}, -- the details to connect to the node manager (ip,port) ---~ } ---~ master.OnError(function(name,err) ---~ print(name.." has encountered an error: "..err) ---~ end) ---~ local connlist = {} ---~ multi:newThread("NodeUpdater",function() ---~ while true do ---~ thread.sleep(1) ---~ for i=1,#connlist do ---~ conn = master:execute("TASK_MAN",connlist[i], multi:getTasksDetails()) ---~ end ---~ end ---~ end) ---~ master.OnNodeConnected(function(name) ---~ table.insert(connlist,name) ---~ end) ---~ multi.OnError(function(...) ---~ print(...) ---~ end) ---~ for i=1,20 do ---~ multi:newLoop(function() ---~ for i=1,500 do ---~ -- ---~ end ---~ end) ---~ end -multi:newThread("Test",function() +local GLOBAL,THREAD = require("multi.integration.lanesManager").init() +nGLOBAL = require("multi.integration.networkManager").init() +local a +function multi:setName(name) + self.Name = name +end +local clock = os.clock +function sleep(n) -- seconds + local t0 = clock() + while clock() - t0 <= n do end +end +master = multi:newMaster{ + name = "Main", -- the name of the master + --noBroadCast = true, -- if using the node manager, set this to true to avoid double connections + managerDetails = {"192.168.1.4",12345}, -- the details to connect to the node manager (ip,port) +} +master.OnError(function(name,err) + print(name.." has encountered an error: "..err) +end) +local connlist = {} +multi:newThread("NodeUpdater",function() while true do - thread.sleep(1) - print(multi:getTasksDetails()) + thread.sleep(.1) + for i=1,#connlist do + conn = master:execute("TASK_MAN",connlist[i], multi:getTasksDetails()) + end end end) +master.OnNodeConnected(function(name) + table.insert(connlist,name) +end) +multi.OnError(function(...) + print(...) +end) + multi:mainloop{ protect = false }