def start_slave(): """Slave 總啟動程序""" log.info('Start slave') # 等待 Master 連接 log.info('Wait for master connecting...') if not message_manager.is_connected(): message = message_manager.receive_message() while message.type is not MessageType.MASTER_UP: continue # 相機系統初始化 camera_system = CameraSystem() camera_system.start() is_master_down = False while True: message = message_manager.receive_message() if message.type is MessageType.MASTER_DOWN: log.warning('Master Down !!') is_master_down = True break log.info('Stop all connectors') camera_system.stop() if is_master_down: restart()
def _run(self): try: while self._running: conn, addr = self._sock.accept() self._connect_queue.put(conn) except OSError as error: log.warning(error)
def _run_master(self): """master 的運作 在為 master 的情況,socket 建立聆聽後會轉交給另一個執行緒 MessageAccepter MessageAccepter 負責把產生連線的對方 socket 傳回 queue 去做監控 """ connect_queue = queue.Queue() sock = self._build_socket() sock.bind(('0.0.0.0', setting.host_address.port)) # 聆聽連線 sock.listen(6) log.info(f'Socket is Listening') # 建立連線交給 Accepter 處理 self._accepter = MessageAccepter(sock, connect_queue) while self._running: # 有新連線的狀況 if not connect_queue.empty(): conn = connect_queue.get() self._node.add_connection(conn) else: # 檢查已連線的 socket 是否有出錯 has_error = None for node in self._node.get_all(): if node.isFinished(): error = node.get_error() if error is not None: log.warning(f'<{node.get_name()[0]}> {error}') has_error = node self._node.remove(node) # 連線有出錯的狀況,送警告訊息給自己 if has_error is not None: self.send_message(MessageType.SLAVE_DOWN, {'node': node}, is_local=True) # 緩衝 loop 的間隔時間 time.sleep(0.01)
def start_master(): """master 總啟動程序""" from utility.message import message_manager from utility.logger import log from utility.define import MessageType from .ui import ui # 初始化 UI from .hardware_trigger import hardware_trigger from .camera import camera_manager from .resolve import resolve_manager log.info('Start Master') ui.show() while True: # Message 接收與觸發 message = message_manager.receive_message() if (message.type is MessageType.LIVE_VIEW_IMAGE or message.type is MessageType.SHOT_IMAGE): camera_manager.receive_image(message) elif message.type is MessageType.CAMERA_STATUS: camera_manager.update_status(message) elif message.type is MessageType.SLAVE_DOWN: camera_manager.stop_capture(message) elif message.type is MessageType.MASTER_DOWN: log.warning('Master closed') break elif message.type is MessageType.RECORD_REPORT: camera_manager.collect_report(message) elif message.type is MessageType.SUBMIT_REPORT: camera_manager.collect_report(message) elif message.type is MessageType.TRIGGER_REPORT: camera_manager.collect_report(message) # 關閉通訊 hardware_trigger.close() message_manager.stop()
def _run_slave(self): """slave 的運作 在為 slave 的情況,socket 會去找 host 並連接 隨時監控連接是否斷訊並做相應處理 """ connected = False while self._running: try: sock = self._build_socket() sock.settimeout(1.0) sock.connect(self._address) sock.settimeout(None) # 連接上後的處理 connected = True self._node.add_connection(sock) self.send_message(MessageType.MASTER_UP, is_local=True) while self._running: # 監測 socket 是否有狀況 for node in self._node.get_all(): node.join(0.01) error = node.get_error() if error is not None: raise error except (ConnectionResetError, ConnectionRefusedError, ConnectionAbortedError, TimeoutError, OSError) as error: # 有狀況時的回報 if connected: log.warning(error) self.send_message(MessageType.MASTER_DOWN, is_local=True) connected = False # connected 的設置是避免不斷報錯 if error.errno == 10054: if current_process().name == 'MainProcess': log.info('hihi') self._node.clear()
def stop_capture(self, message=None): """停止擷取 主要是用在有 slave 斷線的情況,或者要重置相機擷取的格數 """ for camera in self._camera_list.values(): camera.update_status({'state': CameraState.CLOSE.value}) if self._is_capturing and message is not None: node = message.unpack() log.warning(f'Slave [{node.get_name()}] down, restart cameras') time.sleep(1) message_manager.send_message(MessageType.MASTER_DOWN) self._is_capturing = False ui.dispatch_event( UIEventType.TRIGGER, False )
def cast(self, target, func, *arg, **kwargs): if target in self._caster: getattr(self._caster[target], func)(*arg, **kwargs) else: log.warning(f"can't find cast target [{target}]")