Commit 1beb766e authored by vertighel's avatar vertighel
Browse files

Mako: clear stale errors on connect; one loop thread at a time

- Errors from while the camera was unreachable were never cleared, so
  make_response returned HTTP 500 for every later request: the loop
  switch turned itself off even though the loop had started. Clear
  self.error once the connection succeeds.
- stop_looping() now joins the loop thread instead of waiting for
  state 0, and _run_loop() exits when a newer loop thread replaced it:
  a quick off/on no longer leaves two threads acquiring together
  (VmbError.NotFound every second).

Co-Authored-By: default avatarClaude Opus 5.5 <noreply@anthropic.com>
parent 18581fb1
Loading
Loading
Loading
Loading
Loading
+18 −4
Changes for noctua/devices/mako.py: 18 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -125,6 +125,11 @@ class Mako(BaseDevice):
                                log.warning(f"Mako: packet size negotiation skipped: {e}")
                            self._set_throughput_limit(self._cam)
                            Mako.connected.add(self)
                            # Errors accumulate (see check.vmbpy_errors) and
                            # make_response turns any non-empty list into an
                            # HTTP 500: drop the ones left over from while the
                            # camera was unreachable, now that it answers.
                            self.error = []
                        except Exception as e:
                            self._cam = None
                            msg = f"Mako connection failed: {e}"
@@ -366,9 +371,12 @@ class Guider(Mako):
        if not self._looping:
            return
        self.looping = False
        deadline = time.time() + self.loop_exposure + 10.0
        while self.state != 0 and time.time() < deadline:
            time.sleep(0.1)
        # Wait for the loop thread itself to end, not just for state 0:
        # state goes back to 0 after every frame, while the thread may
        # still be alive.
        thread = self._loop_thread
        if thread is not None:
            thread.join(timeout=self.loop_exposure + 10.0)

    def _run_loop(self):
        try:
@@ -383,7 +391,12 @@ class Guider(Mako):
            log.info("Mako: Loop stopped")
            return
        self._last_exptime = self.loop_exposure
        while self._looping:
        # Also stop if a newer loop thread has replaced this one: if the
        # loop is turned off and on again while a frame is still in flight,
        # the old thread would otherwise find _looping True again and keep
        # acquiring together with the new one.
        me = threading.current_thread()
        while self._looping and self._loop_thread is me:
            try:
                self._state         = 2
                self._last_datetime = dt.utcnow().isoformat(timespec='milliseconds')
@@ -397,6 +410,7 @@ class Guider(Mako):
                self._state = 5
                time.sleep(1.0)
        log.info("Mako: Loop stopped")
        if self._loop_thread is me:
            self._state = 0

    # --- Binning ---