def clear(topic, key): """Clear the config for the given topic and keys.""" if not key: a0.Cfg(topic).write("{}") return for k in key: mergepatch = {k: None} if k[0] == "/": parts = k.split("/") mergepatch = {parts[-1]: None} for part in parts[1:-1][::-1]: mergepatch = {part: mergepatch} a0.Cfg(topic).mergepatch(mergepatch)
async def test_aio_cfg(): a0.File.remove(a0.env.topic_tmpl_cfg().replace("{topic}", "topic")) cfg = a0.Cfg("topic") def thread_main(): for i in range(5): time.sleep(0.1) cfg.write("keep going") cfg.write("done") t = threading.Thread(target=thread_main) t.start() assert (await a0.aio_cfg_one("topic")).payload == b"keep going" cnt = 0 async for pkt in a0.aio_cfg("topic"): cnt += 1 assert pkt.payload in [b"keep going", b"done"] if pkt.payload == b"done": break assert cnt == 6 assert (await a0.aio_cfg_one("topic")).payload == b"done" t.join()
def echo(topic, key, format): """Echo the config for the given topic and keys.""" try: cfg = json.loads(a0.Cfg(topic).read().payload) except Exception: cfg = {} if key: queried_cfg = {} for k in key: if k.startswith("/"): ptr = jsonpointer.JsonPointer(k) cfg_level = queried_cfg for part in ptr.parts[:-1]: if part not in cfg_level: cfg_level[part] = {} cfg_level = cfg_level[part] ptr.set(queried_cfg, ptr.get(cfg)) else: queried_cfg[k] = cfg.get(k) cfg = queried_cfg if format == "list": def walk(prefix, node): for key, val in node.items(): name = f"{prefix}/{key}" if type(val) == dict: walk(name, val) else: print(f'"{name}" = {json.dumps(val)}') walk("", cfg) elif format == "json": print(json.dumps(cfg, indent=2))
def test_cfg_write_if_empty(): a0.File.remove(a0.env.topic_tmpl_cfg().replace("{topic}", "topic")) cfg = a0.Cfg("topic") assert cfg.write_if_empty("cfg 0") assert not cfg.write_if_empty("cfg 1") assert cfg.read().payload == b"cfg 0" cfg.write("cfg 2") assert cfg.read().payload == b"cfg 2"
def cfg(): a0.File.remove(a0.env.topic_tmpl_cfg().replace("{topic}", "topic")) cfg = a0.Cfg("topic") cfg.write( json.dumps({ "foo": { "a": "aaa", "b": "bbb", }, "bar": 3, "bat": [1, 2, 3], })) yield cfg
def cli(procs, deps, build, run, force, reset_logs): names = get_proc_names(procs, deps) names = [name for name in names if defined_processes[name].runtime] if not names: util.fail(f"No processes found") down_existing(names, force) if reset_logs: for name in names: a0.File.remove(f"{name}.log.a0") if build: for name in names: proc_def = defined_processes[name] print(f"building {name}...") proc_def.runtime._build(name, proc_def) print(f"built {name}\n") if run: for name in names: print(f"running {name}...") life_cycle.set_ask(name, life_cycle.Ask.UP) if os.fork() != 0: continue os.chdir("/") os.setsid() os.umask(0) if os.fork() != 0: sys.exit(0) proc_def = defined_processes[name] # Set up configuration. with util.common_env_context(proc_def): a0.Cfg(a0.env.topic()).write(json.dumps(proc_def.cfg)) life_cycle.set_launcher_running(name, True) try: asyncio.run( proc_def.runtime._launcher(name, proc_def).run()) except: pass life_cycle.set_launcher_running(name, False) sys.exit(0)
def set(topic, kv): """Set the config for the given topic and keys.""" kv = dict([arg.split("=", 1) for arg in kv]) for key, val in kv.items(): try: val = json.loads(val) except Exception: pass mergepatch = {key: val} if key[0] == "/": parts = key.split("/") mergepatch = {parts[-1]: val} for part in parts[1:-1][::-1]: mergepatch = {part: mergepatch} a0.Cfg(topic).mergepatch(mergepatch)
import threading from fbrp import util import a0 import dataclasses import enum import json import typing import types _TOPIC = "fbrp/state" _CFG = a0.Cfg(_TOPIC) class Ask(enum.Enum): NONE = "NONE" UP = "UP" DOWN = "DOWN" class State(enum.Enum): UNKNOWN = "UNKNOWN" STARTING = "STARTING" STARTED = "STARTED" STOPPING = "STOPPING" STOPPED = "STOPPED" @dataclasses.dataclass(frozen=True) class ProcInfo: ask: Ask state: State