async def created(app, client, object_args): status.get_status(app).connected.set() retv = await client.post('/objects', json={ API_SID_KEY: object_args[OBJECT_SID_KEY], GROUP_LIST_KEY: object_args[GROUP_LIST_KEY], API_TYPE_KEY: object_args[OBJECT_TYPE_KEY], API_DATA_KEY: object_args[OBJECT_DATA_KEY], }) assert retv.status < 400
async def test_system_status(app, client): resp = await response(client.get('/system/status')) assert resp == { 'connected': True, 'synchronized': True, } status.get_status(app).connected.clear() status.get_status(app).disconnected.set() await asyncio.sleep(0.01) resp = await response(client.get('/system/status')) assert resp == { 'connected': False, 'synchronized': False, }
def states(app): state = status.get_status(app) return [ state.disconnected.is_set(), state.connected.is_set(), state.synchronized.is_set(), ]
async def _maintain_connection(self, connect_func: Callable[[], Awaitable[ConnectionResult_]]): last_ok = True while True: try: spark_status = status.get_status(self.app) self._address, self._transport, self._protocol = await connect_func() await self._protocol.connected LOGGER.info(f'Connected {self}') spark_status.disconnected.clear() spark_status.connected.set() last_ok = True await self._protocol.disconnected LOGGER.info(f'Disconnected {self}') spark_status.connected.clear() spark_status.disconnected.set() except CancelledError: with suppress(Exception): await self._transport.close() break except Exception as ex: if last_ok: LOGGER.info(f'Connection failed: {type(ex).__name__}({ex})') last_ok = False await asyncio.sleep(RETRY_INTERVAL_S) finally: # Keep last known address self._transport = None self._protocol = None
async def _broadcast(self): LOGGER.info(f'Starting {self}') try: api = ObjectApi(self.app) spark_status: status.SparkStatus = status.get_status(self.app) except Exception as ex: LOGGER.error(strex(ex), exc_info=True) raise ex while True: try: await spark_status.synchronized.wait() await asyncio.sleep(PUBLISH_INTERVAL_S) if not self._queues: self._current = None continue self._current = await api.all() coros = [q.put(self._current) for q in self._queues] await asyncio.wait_for( asyncio.gather(*coros, return_exceptions=True), PUBLISH_INTERVAL_S) except asyncio.CancelledError: break except Exception as ex: self._current = None warnings.warn(f'{self} encountered an error: {strex(ex)}')
async def _broadcast(app: web.Application, sid: str, exchange: str, routing: str, interval: int ): publisher = events.get_publisher(app) spark_status = status.get_status(app) ctrl = device.get_controller(app) last_broadcast_ok = True while True: try: await spark_status.connected.wait() await asyncio.sleep(interval) obj = await ctrl.read_object({OBJECT_SID_KEY: sid}) await publisher.publish( exchange=exchange, routing=routing, message=obj[OBJECT_DATA_KEY] ) if not last_broadcast_ok: LOGGER.info(f'Remote publisher [{routing}] resumed Ok') last_broadcast_ok = True except CancelledError: break except Exception as ex: if last_broadcast_ok: warnings.warn(f'Remote publisher [{routing}] encountered an error: {strex(ex)}') last_broadcast_ok = False
async def _seed(self): spark_status = status.get_status(self.app) while True: await spark_status.connected.wait() await self._seed_datastore() await self._seed_time() spark_status.synchronized.set() await spark_status.disconnected.wait() spark_status.synchronized.clear()
async def _broadcast(self): try: name = self.app['config']['name'] interval = self.app['config']['broadcast_interval'] exchange = self.app['config']['broadcast_exchange'] if interval <= 0 or self.app['config']['volatile']: LOGGER.info(f'{self} disabled by user') return LOGGER.info(f'Starting {self}') api = ObjectApi(self.app) spark_status = status.get_status(self.app) publisher = events.get_publisher(self.app) last_broadcast_ok = True except Exception as ex: LOGGER.error(f'{type(ex).__name__}: {str(ex)}', exc_info=True) raise ex while True: try: await spark_status.synchronized.wait() await asyncio.sleep(interval) current_objects = { obj[API_SID_KEY]: obj[API_DATA_KEY] for obj in await api.all_logged() if not obj[API_SID_KEY].startswith(GENERATED_ID_PREFIX) } # Don't broadcast when empty if not current_objects: continue await publisher.publish(exchange=exchange, routing=name, message=current_objects) if not last_broadcast_ok: LOGGER.info(f'{self} resumed Ok') last_broadcast_ok = True except CancelledError: break except Exception as ex: if last_broadcast_ok: warnings.warn( f'{self} encountered an error: {type(ex).__name__}({ex})' ) last_broadcast_ok = False
async def check_status(request: web.Request) -> web.Response: """ --- summary: Get service status tags: - Spark - System operationId: controller.spark.system.status produces: - application/json """ _status = status.get_status(request.app) return web.json_response({ 'connected': _status.connected.is_set(), 'synchronized': _status.synchronized.is_set(), })
async def test_codec_config(app, client, cdc): state = status.get_status(app) updated = cdc.update_unit_config({'Temp': 'degF'}) assert updated['Temp'] == 'degF' assert cdc.get_unit_config() == updated # disconnect state.connected.clear() state.disconnected.set() await asyncio.sleep(0.01) # connect state.disconnected.clear() state.connected.set() await asyncio.sleep(0.01) assert cdc.get_unit_config()['Temp'] == 'degC'
async def spark_status(app): return status.get_status(app)
async def disconnect(app): state = status.get_status(app) state.connected.clear() state.disconnected.set() await asyncio.sleep(0.01)
def __init__(self, app: web.Application, wait_sync=True): self._wait_sync = wait_sync self._status = status.get_status(app) self._ctrl: device.SparkController = device.get_controller(app) self._store: twinkeydict.TwinKeyDict = datastore.get_datastore(app)
async def startup(self, app: web.Application): await self._responder.startup(app) status.get_status(app).connected.set()
async def connected(app, client): status.get_status(app).connected.set() status.get_status(app).synchronized.set()