|
@@ -25,7 +25,6 @@ const HOST = os.hostname()
|
|
|
|
|
|
const state = {
|
|
|
workers: [],
|
|
|
- interfaces: [],
|
|
|
ports: [],
|
|
|
connections: [],
|
|
|
lastScan: {
|
|
@@ -136,7 +135,7 @@ async function findWorkers () {
|
|
|
const { data, error, pythonError } = await workerProcess.spawn()
|
|
|
if (error) throw new Error(error)
|
|
|
if (pythonError) throw new Error(pythonError)
|
|
|
- // c. Save the worker in the state.
|
|
|
+ // d. Save the worker in the state.
|
|
|
state.workers.push({
|
|
|
id: md5(`${interfaceName}${workerScript}${mtime}`),
|
|
|
interfaceName,
|
|
@@ -156,6 +155,9 @@ async function workers (parent, args, context, info) {
|
|
|
await findWorkers()
|
|
|
return state.workers.map(worker => ({
|
|
|
...worker,
|
|
|
+ // Find ports
|
|
|
+ ports: ports(worker.interfaceName, args, context, info),
|
|
|
+ // Serialize worker process
|
|
|
workerProcess: workerProcess(worker.workerProcess, args, context, info)
|
|
|
}))
|
|
|
}
|
|
@@ -172,7 +174,10 @@ async function worker (parent, args, context, info) {
|
|
|
if (!worker) {
|
|
|
throw new Error(`Worker id=${id}, interfaceName=${interfaceName} not found`)
|
|
|
}
|
|
|
- return worker
|
|
|
+ return {
|
|
|
+ ...worker,
|
|
|
+ workerProcess: workerProcess(worker.workerProcess, args, context, info)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function workerProcess (parent, args, ctx, info) {
|
|
@@ -197,7 +202,7 @@ function workerProcess (parent, args, ctx, info) {
|
|
|
/**
|
|
|
* PORTS SECTION
|
|
|
*/
|
|
|
-async function findPorts (interfaceName) {
|
|
|
+async function findPorts () {
|
|
|
console.log('find ports.')
|
|
|
// 1. Make sure, workers are updated.
|
|
|
await findWorkers()
|
|
@@ -206,66 +211,80 @@ async function findPorts (interfaceName) {
|
|
|
// if (state.lastScan.ports + 1000 > Date.now()) return null
|
|
|
// state.lastScan.ports = Date.now()
|
|
|
|
|
|
- const portsPromises = state.workers.map(worker => {})
|
|
|
- // Generate all ports for the interface
|
|
|
- const iface = state.interfaces.find(
|
|
|
- iface => iface.interfaceName === interfaceName
|
|
|
- )
|
|
|
-
|
|
|
- const { data, error, pythonError } = await iface.worker.send({
|
|
|
- type: 'ports'
|
|
|
- })
|
|
|
- if (error) throw new Error(error)
|
|
|
- if (pythonError) throw new Error(pythonError)
|
|
|
- console.log(data)
|
|
|
- data.forEach(port => {
|
|
|
- const id = port.name || port.device
|
|
|
- // Skip existing ports
|
|
|
- if (state.ports.find(port => port.id === id)) return null
|
|
|
- const newPort = {
|
|
|
- id,
|
|
|
- interfaceName,
|
|
|
- host: HOST,
|
|
|
- ...port
|
|
|
- }
|
|
|
- state.ports.push(newPort)
|
|
|
- iface.ports.push(newPort)
|
|
|
+ // 3. Loop through all workers to find available ports.
|
|
|
+ const portsPromises = state.workers.map(async worker => {
|
|
|
+ // a) Ask worker for ports.
|
|
|
+ const { data, error, pythonError } = await worker.workerProcess.send({
|
|
|
+ type: 'ports'
|
|
|
+ })
|
|
|
+ if (error) throw new Error(error)
|
|
|
+ if (pythonError) throw new Error(pythonError)
|
|
|
+ console.log(data)
|
|
|
+ // b) Add all ports that are not in the list.
|
|
|
+ data.forEach(port => {
|
|
|
+ const id = port.name || port.device
|
|
|
+ if (state.ports.find(port => port.id === id)) return null
|
|
|
+ const newPort = {
|
|
|
+ id,
|
|
|
+ interfaceName: worker.interfaceName,
|
|
|
+ host: os.hostname(),
|
|
|
+ ...port
|
|
|
+ }
|
|
|
+ state.ports.push(newPort)
|
|
|
+ worker.ports.push(newPort)
|
|
|
+ })
|
|
|
})
|
|
|
+ await Promise.all(portsPromises)
|
|
|
+
|
|
|
console.log('found ports.')
|
|
|
}
|
|
|
|
|
|
async function ports (parent, args, ctx, info) {
|
|
|
- const { force, interfaceName } = args
|
|
|
+ await findPorts()
|
|
|
+ const { interfaceName } = args
|
|
|
const ifName = interfaceName || parent
|
|
|
|
|
|
+ console.log(ifName)
|
|
|
if (ifName) {
|
|
|
- const iface = state.interfaces.find(iface => iface.interfaceName === ifName)
|
|
|
-
|
|
|
- // Try to find ports if necessary
|
|
|
- if (!iface.ports.length || force) await findPorts(ifName)
|
|
|
+ const iface = state.workers.find(iface => iface.interfaceName === ifName)
|
|
|
+ if (!iface) throw new Error(`Interface ${ifName} not found.`)
|
|
|
return iface.ports
|
|
|
} else {
|
|
|
return state.ports
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * OPTIONS SECTION
|
|
|
- */
|
|
|
-async function findOptions (interfaceName) {
|
|
|
- const iface = state.interfaces.find(
|
|
|
- iface => iface.interfaceName === interfaceName
|
|
|
- )
|
|
|
- const { data, error, pythonError } = await iface.worker.send({
|
|
|
- type: 'options'
|
|
|
+async function port (parent, args, ctx, info) {
|
|
|
+ await findPorts()
|
|
|
+ const { id } = args
|
|
|
+ if (!id) throw new Error('Need an id.')
|
|
|
+ const port = state.ports.find(port => port.id === id)
|
|
|
+ return port
|
|
|
+}
|
|
|
+
|
|
|
+async function findOptions () {
|
|
|
+ // 1. Make sure, workers are updated.
|
|
|
+ await findWorkers()
|
|
|
+
|
|
|
+ // 2. Don't check more frequently than once per second.
|
|
|
+ // if (state.lastScan.options + 1000 > Date.now()) return null
|
|
|
+ // state.lastScan.options = Date.now()
|
|
|
+
|
|
|
+ const optionPromises = state.workers.map(async worker => {
|
|
|
+ const {
|
|
|
+ data,
|
|
|
+ error,
|
|
|
+ pythonError
|
|
|
+ } = await worker.workerProcess.pythonShell.send({ type: 'options' })
|
|
|
+ if (error) throw new Error(error)
|
|
|
+ if (pythonError) throw new Error(pythonError)
|
|
|
+ iface.options.push(...data)
|
|
|
})
|
|
|
- if (error) throw new Error(error)
|
|
|
- if (pythonError) throw new Error(pythonError)
|
|
|
- iface.options.push(...data)
|
|
|
+ await Promise.all(optionPromises)
|
|
|
}
|
|
|
|
|
|
async function options (parent, args, ctx, info) {
|
|
|
- if (!parent) throw new Error('Parent needed.')
|
|
|
+ if (!parent) throw new Error('Need a parent.')
|
|
|
const iface = state.interfaces.find(iface => iface.interfaceName === parent)
|
|
|
|
|
|
// Try to find options if necessary
|