Przeglądaj źródła

improved python interface

Tomi Cvetic 5 lat temu
rodzic
commit
7608a5279c

+ 19 - 17
backend/src/interfaces.js

@@ -145,7 +145,7 @@ async function findPorts(interfaceName) {
 
   const { data, error, pythonError } = await iface.worker.send({ type: 'ports' })
   if (error) throw new Error(error)
-  if (typeof pythonError !== "undefined") throw new Error(pythonError)
+  if (pythonError) throw new Error(pythonError)
   data.forEach(port => {
     const id = port.name || port.device
     // Skip existing ports
@@ -180,7 +180,7 @@ async function findOptions(interfaceName) {
   const iface = state.interfaces.find(iface => iface.interfaceName === interfaceName)
   const { data, error, pythonError } = await iface.worker.send({ type: 'options' })
   if (error) throw new Error(error)
-  if (typeof pythonError !== "undefined") throw new Error(pythonError)
+  if (pythonError) throw new Error(pythonError)
   iface.options.push(...data)
 }
 
@@ -237,8 +237,8 @@ async function connect(parent, args, ctx, info) {
     workerInfo: (parent, args, context, info) => workerInfo(pythonWorker, args, context, info)
   }
   const connectionData = await connection.worker.send({ type: 'connect', device })
-  if (spawnData.error) throw new Error(spawnData.error)
-  if (spawnData.pythonError) throw new Error(spawnData.pythonError)
+  if (connectionData.error) throw new Error(connectionData.error)
+  if (connectionData.pythonError) throw new Error(connectionData.pythonError)
   iface.connections.push(connection)
   state.connections.push(connection)
   return connection
@@ -249,7 +249,7 @@ async function connectionCommand(parent, args, ctx, info) {
   const connection = state.connections.find(connection => connection.id === connectionId)
   const { data, error, pythonError } = await connection.worker.send({ type, string, options })
   if (error) throw new Error(JSON.stringify(error))
-  if (typeof pythonError !== "undefined") throw new Error(pythonError)
+  if (pythonError) throw new Error(JSON.stringify(pythonError))
   return data.response
 }
 
@@ -258,30 +258,32 @@ async function endWorker(parent, args, ctx, info) {
   const { id } = args
   const connection = state.connections.find(connection => connection.id === id)
   const { data, error, pythonError } = await connection.worker.end()
-  console.log(data, error, pythonError)
   if (error) throw new Error(JSON.stringify(error))
-  if (typeof pythonError !== "undefined") throw new Error(pythonError)
-  return connection.workerInfo
+  if (pythonError.error !== 0) throw new Error(JSON.stringify(pythonError))
+  return connection.workerInfo()
 }
 
-async function killWorker(parent, args, ctx, info) {
+async function spawnWorker(parent, args, ctx, info) {
   const { id } = args
   const connection = state.connections.find(connection => connection.id === id)
-  const { data, error, pythonError } = await connection.worker.kill()
+  const { data, error, pythonError } = await connection.worker.spawn()
   console.log(data, error, pythonError)
   if (error) throw new Error(JSON.stringify(error))
-  if (typeof pythonError !== "undefined") throw new Error(pythonError)
-  return connection.workerInfo
+  if (pythonError) throw new Error(JSON.stringify(pythonError))
+  const connectionData = await connection.worker.send({ type: 'connect', device: connection.device })
+  if (connectionData.error) throw new Error(connectionData.error)
+  if (connectionData.pythonError) throw new Error(connectionData.pythonError)
+  return connection.workerInfo()
 }
 
-async function spawnWorker(parent, args, ctx, info) {
+async function killWorker(parent, args, ctx, info) {
   const { id } = args
   const connection = state.connections.find(connection => connection.id === id)
-  const { data, error, pythonError } = await connection.worker.spawn()
+  const { data, error, pythonError } = await connection.worker.kill()
   console.log(data, error, pythonError)
-  if (error) throw new Error(error)
-  if (typeof pythonError !== "undefined") throw new Error(error)
-  return connection.workerInfo
+  if (error) throw new Error(JSON.stringify(error))
+  if (pythonError) throw new Error(JSON.stringify(pythonError))
+  return connection.workerInfo()
 }
 
 const resolvers = {

+ 14 - 8
backend/src/pythonWorker.js

@@ -22,6 +22,7 @@ function PythonWorker(workerScript, shellOptions) {
     if (this.pythonShell.exitCode !== null) return { error: `process ${this.pythonShell.pid} already exited with code ${this.pythonShell.exitCode}` }
     await this.commandLock.acquire()
     await this.pythonLock.acquire()
+    console.log(command)
     this.pythonShell.stdin.write(
       // Write the command as a JSON object. 
       //!Don't forget the new-line
@@ -29,16 +30,19 @@ function PythonWorker(workerScript, shellOptions) {
     )
     await this.pythonLock.acquire()
     const pythonError = this.error.pop()
-    if (typeof pythonError !== "undefined") {
+    if (pythonError) {
       this.pythonLock.release()
       this.commandLock.release()
+      console.log({ pythonError })
       return { pythonError }
     }
     const { data, error } = this.data.pop()
     this.pythonLock.release()
     this.commandLock.release()
+    console.log({ data, error })
     return { data, error }
   }
+
   this.spawn = async () => {
     if (this.pythonShell) {
       if (!this.pythonShell.killed && (this.pythonShell.exitCode === null)) {
@@ -56,16 +60,18 @@ function PythonWorker(workerScript, shellOptions) {
       this.pythonLock.release()
     })
     this.pythonShell.stderr.on('data', error => {
-      this.error.push(JSON.parse(error))
+      const jsonError = JSON.parse(error)
+      this.error.push({ error: jsonError })
       this.pythonLock.release()
     })
     this.pythonShell.on('close', error => {
-      this.error.push(JSON.parse(error))
+      const jsonError = JSON.parse(error)
+      this.error.push({ error: jsonError })
       this.pythonLock.release()
     })
     await this.pythonLock.acquire()
     const pythonError = this.error.pop()
-    if (typeof pythonError !== "undefined") {
+    if (pythonError) {
       this.pythonLock.release()
       this.commandLock.release()
       return { pythonError }
@@ -75,6 +81,7 @@ function PythonWorker(workerScript, shellOptions) {
     this.commandLock.release()
     return { data, error }
   }
+
   this.end = async () => {
     if (this.pythonShell.killed) return { error: `process ${this.pythonShell.pid} already killed.` }
     if (this.pythonShell.exitCode !== null) return { error: `process ${this.pythonShell.pid} already exited with code ${this.pythonShell.exitCode}` }
@@ -82,12 +89,10 @@ function PythonWorker(workerScript, shellOptions) {
     await this.pythonLock.acquire()
     this.pythonShell.stdin.end()
     await this.pythonLock.acquire()
-    console.log(this.error, this.data)
     const pythonError = this.error.pop()
-    if (typeof pythonError !== "undefined") {
+    if (pythonError) {
       this.pythonLock.release()
       this.commandLock.release()
-      console.log('checkpoint')
       return { pythonError }
     }
     const { data, error } = this.data.pop()
@@ -95,13 +100,14 @@ function PythonWorker(workerScript, shellOptions) {
     this.commandLock.release()
     return { data, error }
   }
+
   this.kill = async () => {
     if (this.pythonShell.killed) return { error: `process ${this.pythonShell.pid} already killed.` }
     if (this.pythonShell.exitCode !== null) return { error: `process ${this.pythonShell.pid} already exited with code ${this.pythonShell.exitCode}` }
     await this.commandLock.acquire()
     await this.pythonLock.acquire()
     const pythonError = this.error.pop()
-    if (typeof pythonError !== "undefined") {
+    if (pythonError) {
       this.pythonLock.release()
       this.commandLock.release()
       return { pythonError }

+ 6 - 1
backend/src/python_workers/test_worker.py

@@ -9,11 +9,16 @@ class TestClass:
     def __init__(self, device):
         self.timeout = 2
         self.buffer = None
+        self.connected = True
 
     def write(self, string):
+        if not self.connected:
+            raise Exception('Not connected!')
         self.buffer = string
 
     def read(self):
+        if not self.connected:
+            raise Exception('Not connected!')
         buffer = self.buffer
         self.buffer = None
         if buffer is None:
@@ -32,7 +37,7 @@ class TestClass:
         return self.read()
 
     def close(self):
-        pass
+        self.connected = False
 
 
 class TestWorker:

+ 2 - 1
frontend/components/Connection.js

@@ -44,7 +44,8 @@ class Connection extends React.Component {
           type: 'ask',
           string: this.state.command
         }}
-        refetchQueries={[{ query: INTERFACE_LIST }]}>
+        refetchQueries={[{ query: INTERFACE_LIST }]}
+        fetchPolicy='no-cache'>
         {(connectionCommand, { data, error, loading }) => (
           <StyledConnection>
             <h1>Connection</h1>