From 6deb6bb05ca599893b306439716390017944c971 Mon Sep 17 00:00:00 2001
From: Martin Teichmann <martin.teichmann@xfel.eu>
Date: Thu, 11 Jan 2024 09:55:08 +0000
Subject: [PATCH] parallelize keeping operational

now we can keep many terminals operational within the same
EtherCAT roundtrip
---
 ebpfcat/ebpfcat.py       | 26 ++++++++++++++++----------
 ebpfcat/ethercat.py      |  8 +++-----
 ebpfcat/ethercat_test.py |  4 ----
 3 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/ebpfcat/ebpfcat.py b/ebpfcat/ebpfcat.py
index e77a346..dad8462 100644
--- a/ebpfcat/ebpfcat.py
+++ b/ebpfcat/ebpfcat.py
@@ -534,16 +534,22 @@ class SyncGroup(SyncGroupBase):
         return self.current_data
 
     async def to_operational(self):
-        r = await gather(*[t.to_operational() for t in self.terminals])
-
-        while True:
-            for t in self.terminals:
-                state, error = await t.get_state()
-                if state != 8:  # operational
-                    logging.warning(
-                        "terminal is not operational, state is %i", error)
-                await t.to_operational()
-            await sleep(1)
+        try:
+            await gather(*[t.to_operational() for t in self.terminals])
+
+            while True:
+                r = await gather(*[t.to_operational() for t in self.terminals])
+                for t, (state, error, status) in zip(self.terminals, r):
+                    if state is not MachineState.OPERATIONAL:
+                        logging.warning(
+                            "terminal %s was not operational, status was %i",
+                            t, status)
+                await sleep(1)
+        except CancelledError:
+            raise
+        except Exception:
+            logging.exception('to_operational failed')
+            raise
 
     def start(self):
         self.allocate()
diff --git a/ebpfcat/ethercat.py b/ebpfcat/ethercat.py
index 647e4e6..1eb23e4 100644
--- a/ebpfcat/ethercat.py
+++ b/ebpfcat/ethercat.py
@@ -609,17 +609,15 @@ class Terminal:
             await self.ec.roundtrip(ECCmd.FPWR, self.position,
                                     0x0120, "H", 0x11)
             state = MachineState.INIT
-        pos = order.index(state) + 1
-        state = None
-        for current in order[pos:]:
+        for current in order[order.index(state) + 1:]:
+            if state.value >= target.value:
+                return ret
             await self.ec.roundtrip(ECCmd.FPWR, self.position,
                                     0x0120, "H", current.value)
             while current is not state:
                 state, error, status = await self.get_state()
                 if error:
                     raise EtherCatError(f"AL register error {status}")
-            if state.value >= target.value:
-                return ret
 
     async def read(self, start, *args, **kwargs):
         """read data from the terminal at offset `start`
diff --git a/ebpfcat/ethercat_test.py b/ebpfcat/ethercat_test.py
index c691e57..9cef631 100644
--- a/ebpfcat/ethercat_test.py
+++ b/ebpfcat/ethercat_test.py
@@ -162,7 +162,6 @@ class Tests(TestCase):
               "04000200801110000000000000000000000000000000000000000000"
               "3333"), # padding
             0x66554433, # index
-            (ECCmd.FPRD, 2, 304, 'H2xH'),  # get_state
             H("2a10"  # EtherCAT Header, length & type
               "0000334455660280000000000000"  # ID datagram
               # in datagram
@@ -176,7 +175,6 @@ class Tests(TestCase):
               # in datagram
               "04000400801110000000123456780000000000000000000000000100"
               "3333"), # padding
-            (8, 0),  # return state 8, no error
             ]
         with self.assertNoLogs():
             await self.new_data()
@@ -217,7 +215,6 @@ class Tests(TestCase):
               "0500030000110800000000000000000000000000" # out datagram
               "33333333333333333333"), # padding
             0x55443322,  # index
-            (ECCmd.FPRD, 3, 304, 'H2xH'),  # get_state
             H("2210"  # EtherCAT Header, length & type
               "0000223344550280000000000000"  # ID datagram
               "0500030000110800000076980000000000000000" # out datagram
@@ -234,7 +231,6 @@ class Tests(TestCase):
               "0000223344550280000000000000"  # ID datagram
               "0500030000110800000000000000000000000100" # out datagram
               "33333333333333333333"), # padding
-            (8, 0),  # return state 8, no error
             H("2210"  # EtherCAT Header, length & type
               "0000223344550280000000000000"  # ID datagram
               "0500030000110800000000000000000000000100" # out datagram
-- 
GitLab