I think thats all thats needed

This commit is contained in:
Ryan Ward 2018-07-25 12:13:06 -04:00
parent dce6ea201e
commit 88dbb867a7
10 changed files with 454 additions and 19 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
#Changes #Changes
[TOC] [TOC]
Update: 2.0.0 Big update (Lots of additions some changes) Update: 12.0.0 Big update (Lots of additions some changes)
------------------------ ------------------------
**Note:** ~~After doing some testing, I have noticed that using multi-objects are slightly, quite a bit, faster than using (coroutines)multi:newthread(). Only create a thread if there is no other possibility! System threads are different and will improve performance if you know what you are doing. Using a (coroutine)thread as a loop with a timer is slower than using a TLoop! If you do not need the holding features I strongly recommend that you use the multi-objects. This could be due to the scheduler that I am using, and I am looking into improving the performance of the scheduler for (coroutine)threads. This is still a work in progress so expect things to only get better as time passes!~~ This was the reason threadloop was added. It binds the thread scheduler into the mainloop allowing threads to run much faster than before. Also the use of locals is now possible since I am not dealing with seperate objects. And finally reduced function overhead helps keep the threads running better. **Note:** ~~After doing some testing, I have noticed that using multi-objects are slightly, quite a bit, faster than using (coroutines)multi:newthread(). Only create a thread if there is no other possibility! System threads are different and will improve performance if you know what you are doing. Using a (coroutine)thread as a loop with a timer is slower than using a TLoop! If you do not need the holding features I strongly recommend that you use the multi-objects. This could be due to the scheduler that I am using, and I am looking into improving the performance of the scheduler for (coroutine)threads. This is still a work in progress so expect things to only get better as time passes!~~ This was the reason threadloop was added. It binds the thread scheduler into the mainloop allowing threads to run much faster than before. Also the use of locals is now possible since I am not dealing with seperate objects. And finally reduced function overhead helps keep the threads running better.
@ -17,14 +17,16 @@ Update: 2.0.0 Big update (Lots of additions some changes)
Changed: Changed:
- When a (corutine based)thread errors it does not print anymore! Conect to multi.OnError() to get errors when they happen! - When a (corutine based)thread errors it does not print anymore! Conect to multi.OnError() to get errors when they happen!
- Connections get yet another update. Connect takes an additional argument now which is the position in the table that the func should be called. Note: Fire calls methods backwards so 1 is the back and the # of connections (the default value) is the beginning of the call table - Connections get yet another update. Connect takes an additional argument now which is the position in the table that the func should be called. Note: Fire calls methods backwards so 1 is the back and the # of connections (the default value) is the beginning of the call table
- The love2d compat layer has now been revamped allowing module creators to connect to events without the user having to add likes of code for those events. Its all done automagically - The love2d compat layer has now been revamped allowing module creators to connect to events without the user having to add likes of code for those events. Its all done automagically.
- This library is about 8 years old and using 2.0.0 makes it seem young. I changed it to 12.0.0 since it has some huge changes and there were indeed 12 major releases that added some cool things. Going forward I'll use major.minor.bugfix
- multi.OnError() is now required to capture errors that are thrown when in prorected mode.
#Node: #Node:
- node:sendTo(name,data) - node:sendTo(name,data)
- node:pushTo(name,data) - node:pushTo(name,data)
- node:peek() - node:peek()
- node:pop() - node:pop()
- node:getConsole() - node:getConsole() -- has only 1 function print which allows you to print to the master.
#Master: #Master:
- master:doToAll(func) - master:doToAll(func)
@ -40,9 +42,13 @@ Changed:
- master:OnError(nodename, error) -- if a node has an error this is triggered. - master:OnError(nodename, error) -- if a node has an error this is triggered.
#Bugs #Bugs
- Fixed a small typo I made which caused a hard crash when a (coroutine) thread crashes. This only happened if protect was false. Which is now the defualt value for speed reasons. - Fixed a small typo I made which caused a hard crash when a (coroutine) thread crashes. This only happened if protect was true.
#Going forward: #Going forward:
- I am really excited to finally get this update out there, but left one important thing out. enabling of enviroments for each master connected to a node. This would allow a node to isolate code from multiple masters so they cannot interact with each other. This will come out in version 12.1.0 But might take a while due to the job hunt that I am currently going through.
- Another feature that I am on the fence about is adding channels. They would work like queues, but are named so you can seperate the data from different channels where only one portion of can see certain data.
- I also might add a feature that allows different system threads to consume from a network queue if they are spaned on the same physical machine. This is possible at the moment, just doesn't have a dedicated object for handling this seamlessly. You can do this yourself though.
- Another feature that I am thinking of adding is crosstalk which is a setting that would allow nodes to talk to other nodes. I did not add it in this release since there are some issues that need to be worked out and its very messy atm. however since nodes are named. I may allow by default pushing data to another node, but not have the global table to sync since this is where the issue lies.
- Improve Performance - Improve Performance
- Fix supporting libraries (Bin, and net need tons of work) - Fix supporting libraries (Bin, and net need tons of work)
- Look for the bugs - Look for the bugs

View File

@ -7,7 +7,7 @@ nGLOBAL = require("multi.integration.networkManager").init()
-- Act as a master node -- Act as a master node
master = multi:newMaster{ master = multi:newMaster{
name = "Main", -- the name of the master name = "Main", -- the name of the master
--noBroadCast = true, -- if using the node manager, set this to true to avoid double connections --noBroadCast = true, -- if using the node manager, set this to true to save on some cpu cycles
--managerDetails = {"localhost",12345}, -- the details to connect to the node manager (ip,port) --managerDetails = {"localhost",12345}, -- the details to connect to the node manager (ip,port)
} }
-- Send to all the nodes that are connected to the master -- Send to all the nodes that are connected to the master
@ -16,14 +16,14 @@ master.OnError(function(name,err)
end) end)
master.OnNodeConnected(function(name) master.OnNodeConnected(function(name)
print("Lets Go!") print("Lets Go!")
master:newNetworkThread("Thread",function(node) master:newNetworkThread("Thread",function(node) -- spawn a network thread on a node that can execute code and return date
local print = node:getConsole().print -- it is important to define things as local... another thing i could do is fenv to make sure all masters work in a protectd isolated enviroment local print = node:getConsole().print -- it is important to define things as local... another thing i could do is fenv to make sure all masters work in a protectd isolated enviroment
multi:newTLoop(function() multi:newTLoop(function()
print("Yo whats up man!") print("Yo whats up man!")
error("doing a test") error("doing a test")
end,1) end,1)
end) end)
master:execute("RemoteTest",name,1,2,3) master:execute("RemoteTest",name,1,2,3) -- calls a predefined or registered global method on a node
multi:newThread("waiter",function() multi:newThread("waiter",function()
print("Hello!",name) print("Hello!",name)
while true do while true do

View File

@ -5,8 +5,8 @@ nGLOBAL = require("multi.integration.networkManager").init()
node = multi:newNode{ node = multi:newNode{
crossTalk = false, -- default value, allows nodes to talk to eachother. WIP NOT READY YET! crossTalk = false, -- default value, allows nodes to talk to eachother. WIP NOT READY YET!
allowRemoteRegistering = true, -- allows you to register functions from the master on the node, default is false allowRemoteRegistering = true, -- allows you to register functions from the master on the node, default is false
name = nil, --"TESTNODE", -- default value name = nil, --"TESTNODE", -- default value is nil, if nil a random name is generated. Naming nodes are important if you assign each node on a network with a different task
--noBroadCast = true, -- if using the node manager, set this to true to prevent the node from broadcasting --noBroadCast = true, -- if using the node manager, set this to true to save on some cpu cycles
--managerDetails = {"localhost",12345}, -- connects to the node manager if one exists --managerDetails = {"localhost",12345}, -- connects to the node manager if one exists
} }
function RemoteTest(a,b,c) -- a function that we will be executing remotely function RemoteTest(a,b,c) -- a function that we will be executing remotely

View File

@ -23,8 +23,8 @@ SOFTWARE.
]] ]]
local bin = pcall(require,"bin") local bin = pcall(require,"bin")
local multi = {} local multi = {}
multi.Version = "2.0.0" multi.Version = "12.0.0"
multi._VERSION = "2.0.0" multi._VERSION = "12.0.0"
multi.stage = "stable" multi.stage = "stable"
multi.__index = multi multi.__index = multi
multi.Mainloop = {} multi.Mainloop = {}

View File

@ -1,8 +1,8 @@
package = "multi" package = "multi"
version = "1.11.0" version = "12.0-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.11.0", tag = "v12.0.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
@ -27,6 +27,7 @@ build = {
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }

25
samples/sample-master.lua Normal file
View File

@ -0,0 +1,25 @@
-- set up the package
package.path="?/init.lua;?.lua;"..package.path
-- Import the libraries
multi = require("multi")
local GLOBAL, THREAD = require("multi.integration.lanesManager").init()
nGLOBAL = require("multi.integration.networkManager").init()
-- Act as a master node
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 = {"localhost",12345}, -- the details to connect to the node manager (ip,port)
}
master.OnError(function(name,err)
print(name.." has encountered an error: "..err)
end)
master.OnNodeConnected(function(name)
-- name is the name of the node that connected
end)
-- Starting the multitasker
settings = {
priority = 0, -- 0, 1 or 2
protect = false,
}
multi:threadloop(settings) -- both mainloop and threadloop can be used. one pirotizes threads where the other pirotizes multiobjs
--multi:mainloop(settings)

16
samples/sample-node.lua Normal file
View File

@ -0,0 +1,16 @@
package.path="?/init.lua;?.lua;"..package.path
multi = require("multi")
local GLOBAL, THREAD = require("multi.integration.lanesManager").init()
nGLOBAL = require("multi.integration.networkManager").init()
node = multi:newNode{
allowRemoteRegistering = true, -- allows you to register functions from the master on the node, default is false
name = nil, -- default value
--noBroadCast = true, -- if using the node manager, set this to true to prevent the node from broadcasting
--managerDetails = {"localhost",12345}, -- connects to the node manager if one exists
}
settings = {
priority = 0, -- 1 or 2
stopOnError = true, -- if an actor crashes this will prevent it from constantly crashing over and over. You can leave this false and use multi.OnError to handle crashes as well
protect = true, -- always protect a node. Not really needed since all executed xode from a master is protected on execution to prevent issues.
}
multi:mainloop(settings)

View File

@ -0,0 +1,12 @@
package.path="?/init.lua;?.lua;"..package.path
multi = require("multi")
local GLOBAL, THREAD = require("multi.integration.lanesManager").init()
nGLOBAL = require("multi.integration.networkManager").init()
multi:nodeManager(12345) -- Host a node manager on port: 12345
print("Node Manager Running...")
settings = {
priority = 0, -- 1 or 2
protect = false,
}
multi:mainloop(settings)
-- Thats all you need to run the node manager, everything else is done automatically